hgext/record.py
author Durham Goode <durham@fb.com>
Tue, 10 Sep 2013 19:49:34 -0700
changeset 19730 d184bae667e4
parent 19497 e012a20061ed
child 20171 a765611e06dc
permissions -rw-r--r--
log: make file log slow path usable on large repos Running "hg log <pattern or directory>" on large repos took a very, very long time because it first read ctx.files() for every commit before even starting to process the results. This change makes the ctx.files() check lazy, which makes the command start producing results immediately.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     1
# record.py
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     2
#
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     3
# Copyright 2007 Bryan O'Sullivan <bos@serpentine.com>
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9837
diff changeset
     6
# GNU General Public License version 2 or any later version.
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     7
8934
9dda4c73fc3b extensions: change descriptions for extensions providing a few commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8894
diff changeset
     8
'''commands to interactively select changes for commit/qrefresh'''
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     9
7015
6651de7176a0 i18n, record: improve use of translated docstring in prompts
Martin Geisler <mg@daimi.au.dk>
parents: 6965
diff changeset
    10
from mercurial.i18n import gettext, _
18287
eeadc76a7575 record: remove unused import
Idan Kamara <idankk86@gmail.com>
parents: 18266
diff changeset
    11
from mercurial import cmdutil, commands, extensions, hg, patch
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    12
from mercurial import util
13099
a08b49d2f116 record: move copystat() hack out of util.copyfile() and into record
Brodie Rao <brodie@bitheap.org>
parents: 13075
diff changeset
    13
import copy, cStringIO, errno, os, re, shutil, tempfile
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    14
14408
054da1e0afbe record: use cmdutil.command decorator
Idan Kamara <idankk86@gmail.com>
parents: 14407
diff changeset
    15
cmdtable = {}
054da1e0afbe record: use cmdutil.command decorator
Idan Kamara <idankk86@gmail.com>
parents: 14407
diff changeset
    16
command = cmdutil.command(cmdtable)
16743
38caf405d010 hgext: mark all first-party extensions as such
Augie Fackler <raf@durin42.com>
parents: 16683
diff changeset
    17
testedwith = 'internal'
14408
054da1e0afbe record: use cmdutil.command decorator
Idan Kamara <idankk86@gmail.com>
parents: 14407
diff changeset
    18
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    19
lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    20
14597
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
    21
diffopts = [
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
    22
    ('w', 'ignore-all-space', False,
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
    23
     _('ignore white space when comparing lines')),
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
    24
    ('b', 'ignore-space-change', None,
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
    25
     _('ignore changes in the amount of white space')),
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
    26
    ('B', 'ignore-blank-lines', None,
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
    27
     _('ignore changes whose lines are all blank')),
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
    28
]
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
    29
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    30
def scanpatch(fp):
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
    31
    """like patch.iterhunks, but yield different events
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
    32
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
    33
    - ('file',    [header_lines + fromfile + tofile])
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
    34
    - ('context', [context_lines])
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
    35
    - ('hunk',    [hunk_lines])
17425
e95ec38f86b0 fix wording and not-completely-trivial spelling errors and bad docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 17424
diff changeset
    36
    - ('range',   (-start,len, +start,len, proc))
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
    37
    """
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    38
    lr = patch.linereader(fp)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    39
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    40
    def scanwhile(first, p):
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
    41
        """scan lr while predicate holds"""
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    42
        lines = [first]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    43
        while True:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    44
            line = lr.readline()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    45
            if not line:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    46
                break
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    47
            if p(line):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    48
                lines.append(line)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    49
            else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    50
                lr.push(line)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    51
                break
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    52
        return lines
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    53
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    54
    while True:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    55
        line = lr.readline()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    56
        if not line:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    57
            break
13157
82f840109f76 record: teach parsepatch() about non-git style headers
Steve Borho <steve@borho.org>
parents: 13099
diff changeset
    58
        if line.startswith('diff --git a/') or line.startswith('diff -r '):
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    59
            def notheader(line):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    60
                s = line.split(None, 1)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    61
                return not s or s[0] not in ('---', 'diff')
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    62
            header = scanwhile(line, notheader)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    63
            fromfile = lr.readline()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    64
            if fromfile.startswith('---'):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    65
                tofile = lr.readline()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    66
                header += [fromfile, tofile]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    67
            else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    68
                lr.push(fromfile)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    69
            yield 'file', header
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    70
        elif line[0] == ' ':
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    71
            yield 'context', scanwhile(line, lambda l: l[0] in ' \\')
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    72
        elif line[0] in '-+':
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    73
            yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\')
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    74
        else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    75
            m = lines_re.match(line)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    76
            if m:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    77
                yield 'range', m.groups()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    78
            else:
18954
b1639e98e8a1 record: ignore trailing content when parsing patches - introduce 'other' lines
Mads Kiilerich <mads@kiilerich.com>
parents: 18953
diff changeset
    79
                yield 'other', line
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    80
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    81
class header(object):
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
    82
    """patch header
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6163
diff changeset
    83
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17091
diff changeset
    84
    XXX shouldn't we move this to mercurial/patch.py ?
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
    85
    """
13157
82f840109f76 record: teach parsepatch() about non-git style headers
Steve Borho <steve@borho.org>
parents: 13099
diff changeset
    86
    diffgit_re = re.compile('diff --git a/(.*) b/(.*)$')
82f840109f76 record: teach parsepatch() about non-git style headers
Steve Borho <steve@borho.org>
parents: 13099
diff changeset
    87
    diff_re = re.compile('diff -r .* (.*)$')
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    88
    allhunks_re = re.compile('(?:index|new file|deleted file) ')
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    89
    pretty_re = re.compile('(?:new file|deleted file) ')
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    90
    special_re = re.compile('(?:index|new|deleted|copy|rename) ')
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    91
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    92
    def __init__(self, header):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    93
        self.header = header
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    94
        self.hunks = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    95
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    96
    def binary(self):
13294
98f0adfc89e3 record: simplify header methods with util.any
Patrick Mezard <pmezard@gmail.com>
parents: 13293
diff changeset
    97
        return util.any(h.startswith('index ') for h in self.header)
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5129
diff changeset
    98
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    99
    def pretty(self, fp):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   100
        for h in self.header:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   101
            if h.startswith('index '):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   102
                fp.write(_('this modifies a binary file (all or nothing)\n'))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   103
                break
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   104
            if self.pretty_re.match(h):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   105
                fp.write(h)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   106
                if self.binary():
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   107
                    fp.write(_('this is a binary file\n'))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   108
                break
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   109
            if h.startswith('---'):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   110
                fp.write(_('%d hunks, %d lines changed\n') %
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   111
                         (len(self.hunks),
11728
226a328a7ff3 record: count lines changed as the number of lines added or removed
timeless <timeless@gmail.com>
parents: 11564
diff changeset
   112
                          sum([max(h.added, h.removed) for h in self.hunks])))
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   113
                break
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   114
            fp.write(h)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   115
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   116
    def write(self, fp):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   117
        fp.write(''.join(self.header))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   118
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   119
    def allhunks(self):
13294
98f0adfc89e3 record: simplify header methods with util.any
Patrick Mezard <pmezard@gmail.com>
parents: 13293
diff changeset
   120
        return util.any(self.allhunks_re.match(h) for h in self.header)
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   121
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   122
    def files(self):
13157
82f840109f76 record: teach parsepatch() about non-git style headers
Steve Borho <steve@borho.org>
parents: 13099
diff changeset
   123
        match = self.diffgit_re.match(self.header[0])
82f840109f76 record: teach parsepatch() about non-git style headers
Steve Borho <steve@borho.org>
parents: 13099
diff changeset
   124
        if match:
82f840109f76 record: teach parsepatch() about non-git style headers
Steve Borho <steve@borho.org>
parents: 13099
diff changeset
   125
            fromfile, tofile = match.groups()
82f840109f76 record: teach parsepatch() about non-git style headers
Steve Borho <steve@borho.org>
parents: 13099
diff changeset
   126
            if fromfile == tofile:
82f840109f76 record: teach parsepatch() about non-git style headers
Steve Borho <steve@borho.org>
parents: 13099
diff changeset
   127
                return [fromfile]
82f840109f76 record: teach parsepatch() about non-git style headers
Steve Borho <steve@borho.org>
parents: 13099
diff changeset
   128
            return [fromfile, tofile]
82f840109f76 record: teach parsepatch() about non-git style headers
Steve Borho <steve@borho.org>
parents: 13099
diff changeset
   129
        else:
82f840109f76 record: teach parsepatch() about non-git style headers
Steve Borho <steve@borho.org>
parents: 13099
diff changeset
   130
            return self.diff_re.match(self.header[0]).groups()
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   131
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   132
    def filename(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   133
        return self.files()[-1]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   134
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   135
    def __repr__(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   136
        return '<header %s>' % (' '.join(map(repr, self.files())))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   137
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   138
    def special(self):
13294
98f0adfc89e3 record: simplify header methods with util.any
Patrick Mezard <pmezard@gmail.com>
parents: 13293
diff changeset
   139
        return util.any(self.special_re.match(h) for h in self.header)
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   140
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   141
def countchanges(hunk):
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   142
    """hunk -> (n+,n-)"""
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   143
    add = len([h for h in hunk if h[0] == '+'])
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   144
    rem = len([h for h in hunk if h[0] == '-'])
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   145
    return add, rem
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   146
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   147
class hunk(object):
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   148
    """patch hunk
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6163
diff changeset
   149
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   150
    XXX shouldn't we merge this with patch.hunk ?
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   151
    """
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   152
    maxcontext = 3
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   153
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   154
    def __init__(self, header, fromline, toline, proc, before, hunk, after):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   155
        def trimcontext(number, lines):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   156
            delta = len(lines) - self.maxcontext
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   157
            if False and delta > 0:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   158
                return number + delta, lines[:self.maxcontext]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   159
            return number, lines
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   160
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   161
        self.header = header
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   162
        self.fromline, self.before = trimcontext(fromline, before)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   163
        self.toline, self.after = trimcontext(toline, after)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   164
        self.proc = proc
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   165
        self.hunk = hunk
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   166
        self.added, self.removed = countchanges(self.hunk)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   167
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   168
    def write(self, fp):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   169
        delta = len(self.before) + len(self.after)
6949
834f7e069cae record: take diff lines for lack of trailing newlines into account (issue1282)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6212
diff changeset
   170
        if self.after and self.after[-1] == '\\ No newline at end of file\n':
834f7e069cae record: take diff lines for lack of trailing newlines into account (issue1282)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6212
diff changeset
   171
            delta -= 1
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   172
        fromlen = delta + self.removed
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   173
        tolen = delta + self.added
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   174
        fp.write('@@ -%d,%d +%d,%d @@%s\n' %
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   175
                 (self.fromline, fromlen, self.toline, tolen,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   176
                  self.proc and (' ' + self.proc)))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   177
        fp.write(''.join(self.before + self.hunk + self.after))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   178
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   179
    pretty = write
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   180
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   181
    def filename(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   182
        return self.header.filename()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   183
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   184
    def __repr__(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   185
        return '<hunk %r@%d>' % (self.filename(), self.fromline)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   186
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   187
def parsepatch(fp):
13293
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   188
    """patch -> [] of headers -> [] of hunks """
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   189
    class parser(object):
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   190
        """patch parsing state machine"""
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   191
        def __init__(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   192
            self.fromline = 0
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   193
            self.toline = 0
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   194
            self.proc = ''
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   195
            self.header = None
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   196
            self.context = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   197
            self.before = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   198
            self.hunk = []
13293
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   199
            self.headers = []
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   200
11499
324cd681fa47 record: tuple parameter unpacking is deprecated in py3k
Renato Cunha <renatoc@gmail.com>
parents: 11238
diff changeset
   201
        def addrange(self, limits):
324cd681fa47 record: tuple parameter unpacking is deprecated in py3k
Renato Cunha <renatoc@gmail.com>
parents: 11238
diff changeset
   202
            fromstart, fromend, tostart, toend, proc = limits
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   203
            self.fromline = int(fromstart)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   204
            self.toline = int(tostart)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   205
            self.proc = proc
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   206
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   207
        def addcontext(self, context):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   208
            if self.hunk:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   209
                h = hunk(self.header, self.fromline, self.toline, self.proc,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   210
                         self.before, self.hunk, context)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   211
                self.header.hunks.append(h)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   212
                self.fromline += len(self.before) + h.removed
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   213
                self.toline += len(self.before) + h.added
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   214
                self.before = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   215
                self.hunk = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   216
                self.proc = ''
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   217
            self.context = context
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   218
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   219
        def addhunk(self, hunk):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   220
            if self.context:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   221
                self.before = self.context
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   222
                self.context = []
6949
834f7e069cae record: take diff lines for lack of trailing newlines into account (issue1282)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6212
diff changeset
   223
            self.hunk = hunk
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   224
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   225
        def newfile(self, hdr):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   226
            self.addcontext([])
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   227
            h = header(hdr)
13293
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   228
            self.headers.append(h)
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   229
            self.header = h
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   230
18954
b1639e98e8a1 record: ignore trailing content when parsing patches - introduce 'other' lines
Mads Kiilerich <mads@kiilerich.com>
parents: 18953
diff changeset
   231
        def addother(self, line):
b1639e98e8a1 record: ignore trailing content when parsing patches - introduce 'other' lines
Mads Kiilerich <mads@kiilerich.com>
parents: 18953
diff changeset
   232
            pass # 'other' lines are ignored
b1639e98e8a1 record: ignore trailing content when parsing patches - introduce 'other' lines
Mads Kiilerich <mads@kiilerich.com>
parents: 18953
diff changeset
   233
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   234
        def finished(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   235
            self.addcontext([])
13293
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   236
            return self.headers
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   237
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   238
        transitions = {
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   239
            'file': {'context': addcontext,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   240
                     'file': newfile,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   241
                     'hunk': addhunk,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   242
                     'range': addrange},
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   243
            'context': {'file': newfile,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   244
                        'hunk': addhunk,
18954
b1639e98e8a1 record: ignore trailing content when parsing patches - introduce 'other' lines
Mads Kiilerich <mads@kiilerich.com>
parents: 18953
diff changeset
   245
                        'range': addrange,
b1639e98e8a1 record: ignore trailing content when parsing patches - introduce 'other' lines
Mads Kiilerich <mads@kiilerich.com>
parents: 18953
diff changeset
   246
                        'other': addother},
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   247
            'hunk': {'context': addcontext,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   248
                     'file': newfile,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   249
                     'range': addrange},
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   250
            'range': {'context': addcontext,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   251
                      'hunk': addhunk},
18954
b1639e98e8a1 record: ignore trailing content when parsing patches - introduce 'other' lines
Mads Kiilerich <mads@kiilerich.com>
parents: 18953
diff changeset
   252
            'other': {'other': addother},
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   253
            }
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5129
diff changeset
   254
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   255
    p = parser()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   256
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   257
    state = 'context'
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   258
    for newstate, data in scanpatch(fp):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   259
        try:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   260
            p.transitions[state][newstate](p, data)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   261
        except KeyError:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   262
            raise patch.PatchError('unhandled transition: %s -> %s' %
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   263
                                   (state, newstate))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   264
        state = newstate
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   265
    return p.finished()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   266
13293
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   267
def filterpatch(ui, headers):
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   268
    """Interactively filter patch chunks into applied-only chunks"""
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   269
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   270
    def prompt(skipfile, skipall, query, chunk):
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   271
        """prompt query, and process base inputs
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6163
diff changeset
   272
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   273
        - y/n for the rest of file
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   274
        - y/n for the rest
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   275
        - ? (help)
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   276
        - q (quit)
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   277
13291
90e7be23167e record: turn prompt() into a pure function
Patrick Mezard <pmezard@gmail.com>
parents: 13290
diff changeset
   278
        Return True/False and possibly updated skipfile and skipall.
5826
cc43d9f36ff2 record: some docs
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5751
diff changeset
   279
        """
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   280
        newpatches = None
13291
90e7be23167e record: turn prompt() into a pure function
Patrick Mezard <pmezard@gmail.com>
parents: 13290
diff changeset
   281
        if skipall is not None:
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   282
            return skipall, skipfile, skipall, newpatches
13291
90e7be23167e record: turn prompt() into a pure function
Patrick Mezard <pmezard@gmail.com>
parents: 13290
diff changeset
   283
        if skipfile is not None:
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   284
            return skipfile, skipfile, skipall, newpatches
5154
67afecb8d6cc record: improve docs, improve prompts
Bryan O'Sullivan <bos@serpentine.com>
parents: 5147
diff changeset
   285
        while True:
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18954
diff changeset
   286
            resps = _('[Ynesfdaq?]'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18954
diff changeset
   287
                      '$$ &Yes, record this change'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18954
diff changeset
   288
                      '$$ &No, skip this change'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18954
diff changeset
   289
                      '$$ &Edit the change manually'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18954
diff changeset
   290
                      '$$ &Skip remaining changes to this file'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18954
diff changeset
   291
                      '$$ Record remaining changes to this &file'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18954
diff changeset
   292
                      '$$ &Done, skip remaining changes and files'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18954
diff changeset
   293
                      '$$ Record &all changes to all remaining files'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18954
diff changeset
   294
                      '$$ &Quit, recording no changes'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18954
diff changeset
   295
                      '$$ &?')
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18954
diff changeset
   296
            r = ui.promptchoice("%s %s" % (query, resps))
10694
d7732d2df54a record: separate each hunk with a blank line
Martin Geisler <mg@lazybytes.net>
parents: 10323
diff changeset
   297
            ui.write("\n")
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   298
            if r == 8: # ?
7015
6651de7176a0 i18n, record: improve use of translated docstring in prompts
Martin Geisler <mg@daimi.au.dk>
parents: 6965
diff changeset
   299
                doc = gettext(record.__doc__)
11236
cfa6a726ef6d record: better way to find help in docstring
Martin Geisler <mg@aragost.com>
parents: 11235
diff changeset
   300
                c = doc.find('::') + 2
7015
6651de7176a0 i18n, record: improve use of translated docstring in prompts
Martin Geisler <mg@daimi.au.dk>
parents: 6965
diff changeset
   301
                for l in doc[c:].splitlines():
11236
cfa6a726ef6d record: better way to find help in docstring
Martin Geisler <mg@aragost.com>
parents: 11235
diff changeset
   302
                    if l.startswith('      '):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   303
                        ui.write(l.strip(), '\n')
5154
67afecb8d6cc record: improve docs, improve prompts
Bryan O'Sullivan <bos@serpentine.com>
parents: 5147
diff changeset
   304
                continue
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8934
diff changeset
   305
            elif r == 0: # yes
9837
b13474cd1496 record: handle translated prompt correctly
Martin Geisler <mg@lazybytes.net>
parents: 9710
diff changeset
   306
                ret = True
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8934
diff changeset
   307
            elif r == 1: # no
9837
b13474cd1496 record: handle translated prompt correctly
Martin Geisler <mg@lazybytes.net>
parents: 9710
diff changeset
   308
                ret = False
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   309
            elif r == 2: # Edit patch
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   310
                if chunk is None:
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   311
                    ui.write(_('cannot edit patch for whole file'))
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   312
                    ui.write("\n")
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   313
                    continue
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   314
                if chunk.header.binary():
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   315
                    ui.write(_('cannot edit patch for binary file'))
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   316
                    ui.write("\n")
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   317
                    continue
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   318
                # Patch comment based on the Git one (based on comment at end of
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   319
                # http://mercurial.selenic.com/wiki/RecordExtension)
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   320
                phelp = '---' + _("""
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   321
To remove '-' lines, make them ' ' lines (context).
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   322
To remove '+' lines, delete them.
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   323
Lines starting with # will be removed from the patch.
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   325
If the patch applies cleanly, the edited hunk will immediately be
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   326
added to the record list. If it does not apply cleanly, a rejects
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   327
file will be generated: you can use that when you try again. If
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   328
all lines of the hunk are removed, then the edit is aborted and
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   329
the hunk is left unchanged.
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   330
""")
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   331
                (patchfd, patchfn) = tempfile.mkstemp(prefix="hg-editor-",
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   332
                        suffix=".diff", text=True)
16328
d388c3fc8319 record: fix up test issues
Matt Mackall <mpm@selenic.com>
parents: 16324
diff changeset
   333
                ncpatchfp = None
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   334
                try:
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   335
                    # Write the initial patch
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   336
                    f = os.fdopen(patchfd, "w")
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   337
                    chunk.header.write(f)
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   338
                    chunk.write(f)
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   339
                    f.write('\n'.join(['# ' + i for i in phelp.splitlines()]))
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   340
                    f.close()
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   341
                    # Start the editor and wait for it to complete
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   342
                    editor = ui.geteditor()
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   343
                    util.system("%s \"%s\"" % (editor, patchfn),
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   344
                            environ={'HGUSER': ui.username()},
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   345
                            onerr=util.Abort, errprefix=_("edit failed"),
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   346
                            out=ui.fout)
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   347
                    # Remove comment lines
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   348
                    patchfp = open(patchfn)
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   349
                    ncpatchfp = cStringIO.StringIO()
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   350
                    for line in patchfp:
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   351
                        if not line.startswith('#'):
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   352
                            ncpatchfp.write(line)
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   353
                    patchfp.close()
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   354
                    ncpatchfp.seek(0)
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   355
                    newpatches = parsepatch(ncpatchfp)
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   356
                finally:
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   357
                    os.unlink(patchfn)
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   358
                    del ncpatchfp
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   359
                # Signal that the chunk shouldn't be applied as-is, but
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   360
                # provide the new patch to be used instead.
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   361
                ret = False
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   362
            elif r == 3: # Skip
13291
90e7be23167e record: turn prompt() into a pure function
Patrick Mezard <pmezard@gmail.com>
parents: 13290
diff changeset
   363
                ret = skipfile = False
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   364
            elif r == 4: # file (Record remaining)
13291
90e7be23167e record: turn prompt() into a pure function
Patrick Mezard <pmezard@gmail.com>
parents: 13290
diff changeset
   365
                ret = skipfile = True
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   366
            elif r == 5: # done, skip remaining
13291
90e7be23167e record: turn prompt() into a pure function
Patrick Mezard <pmezard@gmail.com>
parents: 13290
diff changeset
   367
                ret = skipall = False
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   368
            elif r == 6: # all
13291
90e7be23167e record: turn prompt() into a pure function
Patrick Mezard <pmezard@gmail.com>
parents: 13290
diff changeset
   369
                ret = skipall = True
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   370
            elif r == 7: # quit
5154
67afecb8d6cc record: improve docs, improve prompts
Bryan O'Sullivan <bos@serpentine.com>
parents: 5147
diff changeset
   371
                raise util.Abort(_('user quit'))
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   372
            return ret, skipfile, skipall, newpatches
13291
90e7be23167e record: turn prompt() into a pure function
Patrick Mezard <pmezard@gmail.com>
parents: 13290
diff changeset
   373
90e7be23167e record: turn prompt() into a pure function
Patrick Mezard <pmezard@gmail.com>
parents: 13290
diff changeset
   374
    seen = set()
90e7be23167e record: turn prompt() into a pure function
Patrick Mezard <pmezard@gmail.com>
parents: 13290
diff changeset
   375
    applied = {}        # 'filename' -> [] of chunks
90e7be23167e record: turn prompt() into a pure function
Patrick Mezard <pmezard@gmail.com>
parents: 13290
diff changeset
   376
    skipfile, skipall = None, None
13295
fb446228c0d4 record: do not include files into changes count
Patrick Mezard <pmezard@gmail.com>
parents: 13294
diff changeset
   377
    pos, total = 1, sum(len(h.hunks) for h in headers)
13293
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   378
    for h in headers:
13295
fb446228c0d4 record: do not include files into changes count
Patrick Mezard <pmezard@gmail.com>
parents: 13294
diff changeset
   379
        pos += len(h.hunks)
13293
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   380
        skipfile = None
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   381
        fixoffset = 0
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   382
        hdr = ''.join(h.header)
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   383
        if hdr in seen:
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   384
            continue
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   385
        seen.add(hdr)
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   386
        if skipall is None:
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   387
            h.pretty(ui)
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   388
        msg = (_('examine changes to %s?') %
17081
b013baa3898e record: fix display of non-ASCII names
Matt Mackall <mpm@selenic.com>
parents: 16328
diff changeset
   389
               _(' and ').join("'%s'" % f for f in h.files()))
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   390
        r, skipfile, skipall, np = prompt(skipfile, skipall, msg, None)
13293
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   391
        if not r:
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   392
            continue
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   393
        applied[h.filename()] = [h]
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   394
        if h.allhunks():
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   395
            applied[h.filename()] += h.hunks
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   396
            continue
ad1b46e4a575 record: refactor the prompt loop
Patrick Mezard <pmezard@gmail.com>
parents: 13291
diff changeset
   397
        for i, chunk in enumerate(h.hunks):
13291
90e7be23167e record: turn prompt() into a pure function
Patrick Mezard <pmezard@gmail.com>
parents: 13290
diff changeset
   398
            if skipfile is None and skipall is None:
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   399
                chunk.pretty(ui)
13773
e5390a8b56db record: replace poor man's if-statement with real if-statement
Martin Geisler <mg@lazybytes.net>
parents: 13295
diff changeset
   400
            if total == 1:
17566
cd73bbc99bdc record: fix display of non-ASCII names in chunk selection
Nikolaj Sjujskij <sterkrig@myopera.com>
parents: 17446
diff changeset
   401
                msg = _("record this change to '%s'?") % chunk.filename()
13773
e5390a8b56db record: replace poor man's if-statement with real if-statement
Martin Geisler <mg@lazybytes.net>
parents: 13295
diff changeset
   402
            else:
e5390a8b56db record: replace poor man's if-statement with real if-statement
Martin Geisler <mg@lazybytes.net>
parents: 13295
diff changeset
   403
                idx = pos - len(h.hunks) + i
17566
cd73bbc99bdc record: fix display of non-ASCII names in chunk selection
Nikolaj Sjujskij <sterkrig@myopera.com>
parents: 17446
diff changeset
   404
                msg = _("record change %d/%d to '%s'?") % (idx, total,
cd73bbc99bdc record: fix display of non-ASCII names in chunk selection
Nikolaj Sjujskij <sterkrig@myopera.com>
parents: 17446
diff changeset
   405
                                                           chunk.filename())
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   406
            r, skipfile, skipall, newpatches = prompt(skipfile,
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   407
                    skipall, msg, chunk)
9837
b13474cd1496 record: handle translated prompt correctly
Martin Geisler <mg@lazybytes.net>
parents: 9710
diff changeset
   408
            if r:
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   409
                if fixoffset:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   410
                    chunk = copy.copy(chunk)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   411
                    chunk.toline += fixoffset
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   412
                applied[chunk.filename()].append(chunk)
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   413
            elif newpatches is not None:
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   414
                for newpatch in newpatches:
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   415
                    for newhunk in newpatch.hunks:
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   416
                        if fixoffset:
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   417
                            newhunk.toline += fixoffset
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   418
                        applied[newhunk.filename()].append(newhunk)
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   419
            else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   420
                fixoffset += chunk.removed - chunk.added
11500
b782a7eb9037 record: removed 'reduce' calls (unsupported by py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11499
diff changeset
   421
    return sum([h for h in applied.itervalues()
b782a7eb9037 record: removed 'reduce' calls (unsupported by py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11499
diff changeset
   422
               if h[0].special() or len(h) > 1], [])
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   423
14408
054da1e0afbe record: use cmdutil.command decorator
Idan Kamara <idankk86@gmail.com>
parents: 14407
diff changeset
   424
@command("record",
14597
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
   425
         # same options as commit + white space diff options
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
   426
         commands.table['^commit|ci'][1][:] + diffopts,
14408
054da1e0afbe record: use cmdutil.command decorator
Idan Kamara <idankk86@gmail.com>
parents: 14407
diff changeset
   427
          _('hg record [OPTION]... [FILE]...'))
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   428
def record(ui, repo, *pats, **opts):
5154
67afecb8d6cc record: improve docs, improve prompts
Bryan O'Sullivan <bos@serpentine.com>
parents: 5147
diff changeset
   429
    '''interactively select changes to commit
67afecb8d6cc record: improve docs, improve prompts
Bryan O'Sullivan <bos@serpentine.com>
parents: 5147
diff changeset
   430
10973
49a07f441496 Use hg role in help strings
Martin Geisler <mg@aragost.com>
parents: 10890
diff changeset
   431
    If a list of files is omitted, all changes reported by :hg:`status`
9272
784899697571 record: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9157
diff changeset
   432
    will be candidates for recording.
5154
67afecb8d6cc record: improve docs, improve prompts
Bryan O'Sullivan <bos@serpentine.com>
parents: 5147
diff changeset
   433
10973
49a07f441496 Use hg role in help strings
Martin Geisler <mg@aragost.com>
parents: 10890
diff changeset
   434
    See :hg:`help dates` for a list of formats valid for -d/--date.
6163
1f733c2f0165 Document log date ranges and mention 'hg help dates' for all commands (issue998)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5932
diff changeset
   435
9272
784899697571 record: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9157
diff changeset
   436
    You will be prompted for whether to record changes to each
784899697571 record: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9157
diff changeset
   437
    modified file, and for files with multiple changes, for each
784899697571 record: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9157
diff changeset
   438
    change to use. For each query, the following responses are
784899697571 record: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9157
diff changeset
   439
    possible::
5154
67afecb8d6cc record: improve docs, improve prompts
Bryan O'Sullivan <bos@serpentine.com>
parents: 5147
diff changeset
   440
9157
9261667e9b82 commands: use minirst parser when displaying help
Martin Geisler <mg@lazybytes.net>
parents: 9087
diff changeset
   441
      y - record this change
9261667e9b82 commands: use minirst parser when displaying help
Martin Geisler <mg@lazybytes.net>
parents: 9087
diff changeset
   442
      n - skip this change
16324
46b991a1f428 record: allow splitting of hunks by manually editing patches
A. S. Budden <abudden@gmail.com>
parents: 15184
diff changeset
   443
      e - edit this change manually
5154
67afecb8d6cc record: improve docs, improve prompts
Bryan O'Sullivan <bos@serpentine.com>
parents: 5147
diff changeset
   444
9157
9261667e9b82 commands: use minirst parser when displaying help
Martin Geisler <mg@lazybytes.net>
parents: 9087
diff changeset
   445
      s - skip remaining changes to this file
9261667e9b82 commands: use minirst parser when displaying help
Martin Geisler <mg@lazybytes.net>
parents: 9087
diff changeset
   446
      f - record remaining changes to this file
5154
67afecb8d6cc record: improve docs, improve prompts
Bryan O'Sullivan <bos@serpentine.com>
parents: 5147
diff changeset
   447
9157
9261667e9b82 commands: use minirst parser when displaying help
Martin Geisler <mg@lazybytes.net>
parents: 9087
diff changeset
   448
      d - done, skip remaining changes and files
9261667e9b82 commands: use minirst parser when displaying help
Martin Geisler <mg@lazybytes.net>
parents: 9087
diff changeset
   449
      a - record all changes to all remaining files
9261667e9b82 commands: use minirst parser when displaying help
Martin Geisler <mg@lazybytes.net>
parents: 9087
diff changeset
   450
      q - quit, recording no changes
5154
67afecb8d6cc record: improve docs, improve prompts
Bryan O'Sullivan <bos@serpentine.com>
parents: 5147
diff changeset
   451
11237
feb2a58fc592 record: check that we are not committing a merge before patch selection
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11236
diff changeset
   452
      ? - display help
feb2a58fc592 record: check that we are not committing a merge before patch selection
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11236
diff changeset
   453
feb2a58fc592 record: check that we are not committing a merge before patch selection
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11236
diff changeset
   454
    This command is not available when committing a merge.'''
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   455
14425
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   456
    dorecord(ui, repo, commands.commit, 'commit', False, *pats, **opts)
5830
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   457
15184
351a9292e430 record: use command wrapper properly for qnew/qrefresh (issue3001)
Matt Mackall <mpm@selenic.com>
parents: 14597
diff changeset
   458
def qrefresh(origfn, ui, repo, *pats, **opts):
351a9292e430 record: use command wrapper properly for qnew/qrefresh (issue3001)
Matt Mackall <mpm@selenic.com>
parents: 14597
diff changeset
   459
    if not opts['interactive']:
351a9292e430 record: use command wrapper properly for qnew/qrefresh (issue3001)
Matt Mackall <mpm@selenic.com>
parents: 14597
diff changeset
   460
        return origfn(ui, repo, *pats, **opts)
351a9292e430 record: use command wrapper properly for qnew/qrefresh (issue3001)
Matt Mackall <mpm@selenic.com>
parents: 14597
diff changeset
   461
14426
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   462
    mq = extensions.find('mq')
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   463
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   464
    def committomq(ui, repo, *pats, **opts):
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   465
        # At this point the working copy contains only changes that
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   466
        # were accepted. All other changes were reverted.
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   467
        # We can't pass *pats here since qrefresh will undo all other
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   468
        # changed files in the patch that aren't in pats.
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   469
        mq.refresh(ui, repo, **opts)
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   470
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   471
    # backup all changed files
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   472
    dorecord(ui, repo, committomq, 'qrefresh', True, *pats, **opts)
5830
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   473
5932
b014ff3fdaeb qrecord: record complements commit, so qrecord should complement qnew
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5830
diff changeset
   474
def qrecord(ui, repo, patch, *pats, **opts):
b014ff3fdaeb qrecord: record complements commit, so qrecord should complement qnew
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5830
diff changeset
   475
    '''interactively record a new patch
5830
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   476
10973
49a07f441496 Use hg role in help strings
Martin Geisler <mg@aragost.com>
parents: 10890
diff changeset
   477
    See :hg:`help qnew` & :hg:`help record` for more information and
9272
784899697571 record: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9157
diff changeset
   478
    usage.
5830
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   479
    '''
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   480
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   481
    try:
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   482
        mq = extensions.find('mq')
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   483
    except KeyError:
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   484
        raise util.Abort(_("'mq' extension not loaded"))
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   485
14424
4eb88d296f63 record: check patch name is valid before prompting in qrecord
Idan Kamara <idankk86@gmail.com>
parents: 14408
diff changeset
   486
    repo.mq.checkpatchname(patch)
4eb88d296f63 record: check patch name is valid before prompting in qrecord
Idan Kamara <idankk86@gmail.com>
parents: 14408
diff changeset
   487
10323
0aa59f532ef9 record: function variable naming & signature cleanup.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10282
diff changeset
   488
    def committomq(ui, repo, *pats, **opts):
14424
4eb88d296f63 record: check patch name is valid before prompting in qrecord
Idan Kamara <idankk86@gmail.com>
parents: 14408
diff changeset
   489
        opts['checkname'] = False
5932
b014ff3fdaeb qrecord: record complements commit, so qrecord should complement qnew
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5830
diff changeset
   490
        mq.new(ui, repo, patch, *pats, **opts)
5830
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   491
14425
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   492
    dorecord(ui, repo, committomq, 'qnew', False, *pats, **opts)
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   493
15184
351a9292e430 record: use command wrapper properly for qnew/qrefresh (issue3001)
Matt Mackall <mpm@selenic.com>
parents: 14597
diff changeset
   494
def qnew(origfn, ui, repo, patch, *args, **opts):
351a9292e430 record: use command wrapper properly for qnew/qrefresh (issue3001)
Matt Mackall <mpm@selenic.com>
parents: 14597
diff changeset
   495
    if opts['interactive']:
351a9292e430 record: use command wrapper properly for qnew/qrefresh (issue3001)
Matt Mackall <mpm@selenic.com>
parents: 14597
diff changeset
   496
        return qrecord(ui, repo, patch, *args, **opts)
351a9292e430 record: use command wrapper properly for qnew/qrefresh (issue3001)
Matt Mackall <mpm@selenic.com>
parents: 14597
diff changeset
   497
    return origfn(ui, repo, patch, *args, **opts)
351a9292e430 record: use command wrapper properly for qnew/qrefresh (issue3001)
Matt Mackall <mpm@selenic.com>
parents: 14597
diff changeset
   498
14425
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   499
def dorecord(ui, repo, commitfunc, cmdsuggest, backupall, *pats, **opts):
8208
32a2a1e244f1 ui: make interactive a method
Matt Mackall <mpm@selenic.com>
parents: 8152
diff changeset
   500
    if not ui.interactive():
14407
51cabd567ac6 record: suggest the right command when running non interactively
Idan Kamara <idankk86@gmail.com>
parents: 14370
diff changeset
   501
        raise util.Abort(_('running non-interactively, use %s instead') %
51cabd567ac6 record: suggest the right command when running non interactively
Idan Kamara <idankk86@gmail.com>
parents: 14370
diff changeset
   502
                         cmdsuggest)
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   503
17446
3de04c07966a record: checks for valid username before starting recording process (issue3456)
Sumeet <sumeet@fb.com>
parents: 17425
diff changeset
   504
    # make sure username is set before going interactive
3de04c07966a record: checks for valid username before starting recording process (issue3456)
Sumeet <sumeet@fb.com>
parents: 17425
diff changeset
   505
    ui.username()
3de04c07966a record: checks for valid username before starting recording process (issue3456)
Sumeet <sumeet@fb.com>
parents: 17425
diff changeset
   506
6600
b822a379860b match: stop passing files through commitfunc
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
   507
    def recordfunc(ui, repo, message, match, opts):
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   508
        """This is generic record driver.
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   509
13195
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   510
        Its job is to interactively filter local changes, and
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   511
        accordingly prepare working directory into a state in which the
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   512
        job can be delegated to a non-interactive commit command such as
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   513
        'commit' or 'qrefresh'.
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   514
13195
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   515
        After the actual job is done by non-interactive command, the
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   516
        working directory is restored to its original state.
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   517
13195
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   518
        In the end we'll record interesting changes, and everything else
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   519
        will be left in place, so the user can continue working.
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   520
        """
7754
ab00d2c281a8 record: minimize number of status calls
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7718
diff changeset
   521
19497
e012a20061ed record: add checkunfinished support (issue3955)
Matt Mackall <mpm@selenic.com>
parents: 19226
diff changeset
   522
        cmdutil.checkunfinished(repo, commit=True)
11237
feb2a58fc592 record: check that we are not committing a merge before patch selection
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11236
diff changeset
   523
        merge = len(repo[None].parents()) > 1
feb2a58fc592 record: check that we are not committing a merge before patch selection
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11236
diff changeset
   524
        if merge:
feb2a58fc592 record: check that we are not committing a merge before patch selection
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11236
diff changeset
   525
            raise util.Abort(_('cannot partially commit a merge '
13023
3e2281b85990 record: quote command in use hg commit message
timeless <timeless@gmail.com>
parents: 12674
diff changeset
   526
                               '(use "hg commit" instead)'))
11237
feb2a58fc592 record: check that we are not committing a merge before patch selection
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11236
diff changeset
   527
7754
ab00d2c281a8 record: minimize number of status calls
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7718
diff changeset
   528
        changes = repo.status(match=match)[:3]
18266
09a2b6741695 record: use patch.diffopts to account for user diffopts
Denis Laxalde <denis@laxalde.org>
parents: 17773
diff changeset
   529
        diffopts = patch.diffopts(ui, opts=dict(
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16328
diff changeset
   530
            git=True, nodates=True,
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16328
diff changeset
   531
            ignorews=opts.get('ignore_all_space'),
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16328
diff changeset
   532
            ignorewsamount=opts.get('ignore_space_change'),
18266
09a2b6741695 record: use patch.diffopts to account for user diffopts
Denis Laxalde <denis@laxalde.org>
parents: 17773
diff changeset
   533
            ignoreblanklines=opts.get('ignore_blank_lines')))
7754
ab00d2c281a8 record: minimize number of status calls
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7718
diff changeset
   534
        chunks = patch.diff(repo, changes=changes, opts=diffopts)
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   535
        fp = cStringIO.StringIO()
7308
b6f5490effbf patch: turn patch.diff() into a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7015
diff changeset
   536
        fp.write(''.join(chunks))
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   537
        fp.seek(0)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   538
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   539
        # 1. filter patch, so we have intending-to apply subset of it
18953
e4ae397595e8 record: abort on malformed patches instead of crashing
Mads Kiilerich <madski@unity3d.com>
parents: 18287
diff changeset
   540
        try:
e4ae397595e8 record: abort on malformed patches instead of crashing
Mads Kiilerich <madski@unity3d.com>
parents: 18287
diff changeset
   541
            chunks = filterpatch(ui, parsepatch(fp))
e4ae397595e8 record: abort on malformed patches instead of crashing
Mads Kiilerich <madski@unity3d.com>
parents: 18287
diff changeset
   542
        except patch.PatchError, err:
e4ae397595e8 record: abort on malformed patches instead of crashing
Mads Kiilerich <madski@unity3d.com>
parents: 18287
diff changeset
   543
            raise util.Abort(_('error parsing patch: %s') % err)
e4ae397595e8 record: abort on malformed patches instead of crashing
Mads Kiilerich <madski@unity3d.com>
parents: 18287
diff changeset
   544
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   545
        del fp
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   546
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 7983
diff changeset
   547
        contenders = set()
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   548
        for h in chunks:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   549
            try:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   550
                contenders.update(set(h.files()))
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   551
            except AttributeError:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   552
                pass
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5129
diff changeset
   553
7754
ab00d2c281a8 record: minimize number of status calls
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7718
diff changeset
   554
        changed = changes[0] + changes[1] + changes[2]
ab00d2c281a8 record: minimize number of status calls
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7718
diff changeset
   555
        newfiles = [f for f in changed if f in contenders]
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   556
        if not newfiles:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   557
            ui.status(_('no changes to record\n'))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   558
            return 0
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   559
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 7983
diff changeset
   560
        modified = set(changes[0])
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   561
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   562
        # 2. backup changed files, so we can restore them in the end
14425
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   563
        if backupall:
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   564
            tobackup = changed
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   565
        else:
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   566
            tobackup = [f for f in newfiles if f in modified]
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   567
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   568
        backups = {}
14425
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   569
        if tobackup:
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   570
            backupdir = repo.join('record-backups')
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   571
            try:
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   572
                os.mkdir(backupdir)
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   573
            except OSError, err:
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   574
                if err.errno != errno.EEXIST:
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   575
                    raise
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   576
        try:
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   577
            # backup continues
14425
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   578
            for f in tobackup:
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   579
                fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   580
                                               dir=backupdir)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   581
                os.close(fd)
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9272
diff changeset
   582
                ui.debug('backup %r as %r\n' % (f, tmpname))
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   583
                util.copyfile(repo.wjoin(f), tmpname)
13099
a08b49d2f116 record: move copystat() hack out of util.copyfile() and into record
Brodie Rao <brodie@bitheap.org>
parents: 13075
diff changeset
   584
                shutil.copystat(repo.wjoin(f), tmpname)
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   585
                backups[f] = tmpname
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   586
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   587
            fp = cStringIO.StringIO()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   588
            for c in chunks:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   589
                if c.filename() in backups:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   590
                    c.write(fp)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   591
            dopatch = fp.tell()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   592
            fp.seek(0)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   593
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   594
            # 3a. apply filtered patch to clean repo  (clean)
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   595
            if backups:
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 13773
diff changeset
   596
                hg.revert(repo, repo.dirstate.p1(),
11564
9bbfeba33aa3 record: removed 'has_key' usage
Renato Cunha <renatoc@gmail.com>
parents: 11500
diff changeset
   597
                          lambda key: key in backups)
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   598
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   599
            # 3b. (apply)
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   600
            if dopatch:
6950
381a892159d9 record: catch PatchErrors from internalpatch and display error message
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6949
diff changeset
   601
                try:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9272
diff changeset
   602
                    ui.debug('applying patch\n')
6950
381a892159d9 record: catch PatchErrors from internalpatch and display error message
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6949
diff changeset
   603
                    ui.debug(fp.getvalue())
14370
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14260
diff changeset
   604
                    patch.internalpatch(ui, repo, fp, 1, eolmode=None)
6950
381a892159d9 record: catch PatchErrors from internalpatch and display error message
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6949
diff changeset
   605
                except patch.PatchError, err:
12674
aa2fe1f52ff4 patch: always raise PatchError with a message, simplify handling
Patrick Mezard <pmezard@gmail.com>
parents: 12266
diff changeset
   606
                    raise util.Abort(str(err))
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   607
            del fp
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   608
13195
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   609
            # 4. We prepared working directory according to filtered
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   610
            #    patch. Now is the time to delegate the job to
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   611
            #    commit/qrefresh or the like!
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   612
13195
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   613
            # it is important to first chdir to repo root -- we'll call
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   614
            # a highlevel command with list of pathnames relative to
f14cfcc488fb record: clean up comments and docstrings
Kevin Bullock <kbullock@ringworld.org>
parents: 13157
diff changeset
   615
            # repo root
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   616
            cwd = os.getcwd()
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   617
            os.chdir(repo.root)
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   618
            try:
10323
0aa59f532ef9 record: function variable naming & signature cleanup.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10282
diff changeset
   619
                commitfunc(ui, repo, *newfiles, **opts)
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   620
            finally:
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   621
                os.chdir(cwd)
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   622
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   623
            return 0
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   624
        finally:
5827
0c29977bd7db record: refactor record into generic record driver
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5826
diff changeset
   625
            # 5. finally restore backed-up files
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   626
            try:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   627
                for realname, tmpname in backups.iteritems():
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9272
diff changeset
   628
                    ui.debug('restoring %r to %r\n' % (tmpname, realname))
5128
c9126c24e098 record: work properly if invoked in a subdirectory
Bryan O'Sullivan <bos@serpentine.com>
parents: 5040
diff changeset
   629
                    util.copyfile(tmpname, repo.wjoin(realname))
13099
a08b49d2f116 record: move copystat() hack out of util.copyfile() and into record
Brodie Rao <brodie@bitheap.org>
parents: 13075
diff changeset
   630
                    # Our calls to copystat() here and above are a
a08b49d2f116 record: move copystat() hack out of util.copyfile() and into record
Brodie Rao <brodie@bitheap.org>
parents: 13075
diff changeset
   631
                    # hack to trick any editors that have f open that
a08b49d2f116 record: move copystat() hack out of util.copyfile() and into record
Brodie Rao <brodie@bitheap.org>
parents: 13075
diff changeset
   632
                    # we haven't modified them.
a08b49d2f116 record: move copystat() hack out of util.copyfile() and into record
Brodie Rao <brodie@bitheap.org>
parents: 13075
diff changeset
   633
                    #
a08b49d2f116 record: move copystat() hack out of util.copyfile() and into record
Brodie Rao <brodie@bitheap.org>
parents: 13075
diff changeset
   634
                    # Also note that this racy as an editor could
a08b49d2f116 record: move copystat() hack out of util.copyfile() and into record
Brodie Rao <brodie@bitheap.org>
parents: 13075
diff changeset
   635
                    # notice the file's mtime before we've finished
a08b49d2f116 record: move copystat() hack out of util.copyfile() and into record
Brodie Rao <brodie@bitheap.org>
parents: 13075
diff changeset
   636
                    # writing it.
a08b49d2f116 record: move copystat() hack out of util.copyfile() and into record
Brodie Rao <brodie@bitheap.org>
parents: 13075
diff changeset
   637
                    shutil.copystat(tmpname, repo.wjoin(realname))
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   638
                    os.unlink(tmpname)
14425
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   639
                if tobackup:
e89534504fb9 record: add an option to backup all wc modifications
Idan Kamara <idankk86@gmail.com>
parents: 14424
diff changeset
   640
                    os.rmdir(backupdir)
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   641
            except OSError:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   642
                pass
10825
781689b9b6bb record: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10694
diff changeset
   643
781689b9b6bb record: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10694
diff changeset
   644
    # wrap ui.write so diff output can be labeled/colorized
781689b9b6bb record: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10694
diff changeset
   645
    def wrapwrite(orig, *args, **kw):
781689b9b6bb record: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10694
diff changeset
   646
        label = kw.pop('label', '')
781689b9b6bb record: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10694
diff changeset
   647
        for chunk, l in patch.difflabel(lambda: args):
781689b9b6bb record: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10694
diff changeset
   648
            orig(chunk, label=label + l)
781689b9b6bb record: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10694
diff changeset
   649
    oldwrite = ui.write
781689b9b6bb record: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10694
diff changeset
   650
    extensions.wrapfunction(ui, 'write', wrapwrite)
781689b9b6bb record: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10694
diff changeset
   651
    try:
781689b9b6bb record: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10694
diff changeset
   652
        return cmdutil.commit(ui, repo, recordfunc, pats, opts)
781689b9b6bb record: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10694
diff changeset
   653
    finally:
781689b9b6bb record: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10694
diff changeset
   654
        ui.write = oldwrite
5037
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   655
14408
054da1e0afbe record: use cmdutil.command decorator
Idan Kamara <idankk86@gmail.com>
parents: 14407
diff changeset
   656
cmdtable["qrecord"] = \
14441
39e81b9377e6 record: fix options placeholder
Idan Kamara <idankk86@gmail.com>
parents: 14427
diff changeset
   657
    (qrecord, [], # placeholder until mq is available
14408
054da1e0afbe record: use cmdutil.command decorator
Idan Kamara <idankk86@gmail.com>
parents: 14407
diff changeset
   658
     _('hg qrecord [OPTION]... PATCH [FILE]...'))
5830
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   659
9710
1765599f4899 record: use uisetup instead of extsetup to register qrecord
Martin Geisler <mg@lazybytes.net>
parents: 9688
diff changeset
   660
def uisetup(ui):
5830
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   661
    try:
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   662
        mq = extensions.find('mq')
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   663
    except KeyError:
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   664
        return
c32d41affb68 hg qrecord -- like record, but for mq
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5827
diff changeset
   665
14408
054da1e0afbe record: use cmdutil.command decorator
Idan Kamara <idankk86@gmail.com>
parents: 14407
diff changeset
   666
    cmdtable["qrecord"] = \
14427
9d4cabd189df record: alias qrecord to qnew -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14426
diff changeset
   667
        (qrecord,
9d4cabd189df record: alias qrecord to qnew -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14426
diff changeset
   668
         # same options as qnew, but copy them so we don't get
14597
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
   669
         # -i/--interactive for qrecord and add white space diff options
3f1dccea9510 record: add white space diff options
Ingo Proetel <proetel@aicas.de>
parents: 14441
diff changeset
   670
         mq.cmdtable['^qnew'][1][:] + diffopts,
14408
054da1e0afbe record: use cmdutil.command decorator
Idan Kamara <idankk86@gmail.com>
parents: 14407
diff changeset
   671
         _('hg qrecord [OPTION]... PATCH [FILE]...'))
14426
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   672
15184
351a9292e430 record: use command wrapper properly for qnew/qrefresh (issue3001)
Matt Mackall <mpm@selenic.com>
parents: 14597
diff changeset
   673
    _wrapcmd('qnew', mq.cmdtable, qnew, _("interactively record a new patch"))
14426
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   674
    _wrapcmd('qrefresh', mq.cmdtable, qrefresh,
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   675
             _("interactively select changes to refresh"))
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   676
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   677
def _wrapcmd(cmd, table, wrapfn, msg):
15184
351a9292e430 record: use command wrapper properly for qnew/qrefresh (issue3001)
Matt Mackall <mpm@selenic.com>
parents: 14597
diff changeset
   678
    entry = extensions.wrapcommand(table, cmd, wrapfn)
14426
1df64ccef23e record: add qrefresh -i/--interactive
Idan Kamara <idankk86@gmail.com>
parents: 14425
diff changeset
   679
    entry[1].append(('i', 'interactive', None, msg))
17773
434e5bd615fc commands: don't infer repo for commands like update (issue2748)
Siddharth Agarwal <sid0@fb.com>
parents: 17566
diff changeset
   680
434e5bd615fc commands: don't infer repo for commands like update (issue2748)
Siddharth Agarwal <sid0@fb.com>
parents: 17566
diff changeset
   681
commands.inferrepo += " record qrecord"