annotate hgext/record.py @ 5040:4f34d9b2568e

Update style of record's cmdtable to match mercurial/commands.py
author Thomas Arendsen Hein <thomas@intevation.de>
date Wed, 01 Aug 2007 10:42:42 +0200
parents b2607267236d
children c9126c24e098
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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 #
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
6 # the GNU General Public License, incorporated herein by reference.
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
7
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
8 '''interactive change selection during commit'''
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
9
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
10 from mercurial.i18n import _
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
11 from mercurial import cmdutil, commands, cmdutil, hg, mdiff, patch, revlog
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
12 from mercurial import util
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
13 import copy, cStringIO, errno, operator, os, re, shutil, tempfile
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
14
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
15 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
16
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
17 def scanpatch(fp):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
18 lr = patch.linereader(fp)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
19
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
20 def scanwhile(first, p):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
21 lines = [first]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
22 while True:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
23 line = lr.readline()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
24 if not line:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
25 break
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
26 if p(line):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
27 lines.append(line)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
28 else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
29 lr.push(line)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
30 break
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
31 return lines
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
32
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
33 while True:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
34 line = lr.readline()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
35 if not line:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
36 break
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
37 if line.startswith('diff --git a/'):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
38 def notheader(line):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
39 s = line.split(None, 1)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
40 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
41 header = scanwhile(line, notheader)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
42 fromfile = lr.readline()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
43 if fromfile.startswith('---'):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
44 tofile = lr.readline()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
45 header += [fromfile, tofile]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
46 else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
47 lr.push(fromfile)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
48 yield 'file', header
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
49 elif line[0] == ' ':
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
50 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
51 elif line[0] in '-+':
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
52 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
53 else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
54 m = lines_re.match(line)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
55 if m:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
56 yield 'range', m.groups()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
57 else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
58 raise patch.PatchError('unknown patch content: %r' % line)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
59
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
60 class header(object):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
61 diff_re = re.compile('diff --git a/(.*) b/(.*)$')
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
62 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
63 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
64 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
65
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
66 def __init__(self, header):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
67 self.header = header
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
68 self.hunks = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
69
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
70 def binary(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
71 for h in self.header:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
72 if h.startswith('index '):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
73 return True
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
74
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
75 def pretty(self, fp):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
76 for h in self.header:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
77 if h.startswith('index '):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
78 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
79 break
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
80 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
81 fp.write(h)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
82 if self.binary():
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
83 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
84 break
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
85 if h.startswith('---'):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
86 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
87 (len(self.hunks),
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
88 sum([h.added + h.removed for h in self.hunks])))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
89 break
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
90 fp.write(h)
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 write(self, fp):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
93 fp.write(''.join(self.header))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
94
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
95 def allhunks(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
96 for h in self.header:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
97 if self.allhunks_re.match(h):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
98 return True
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
99
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
100 def files(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
101 fromfile, tofile = self.diff_re.match(self.header[0]).groups()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
102 if fromfile == tofile:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
103 return [fromfile]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
104 return [fromfile, tofile]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
105
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
106 def filename(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
107 return self.files()[-1]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
108
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
109 def __repr__(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
110 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
111
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
112 def special(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
113 for h in self.header:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
114 if self.special_re.match(h):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
115 return True
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
116
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
117 def countchanges(hunk):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
118 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
119 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
120 return add, rem
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 class hunk(object):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
123 maxcontext = 3
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
124
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
125 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
126 def trimcontext(number, lines):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
127 delta = len(lines) - self.maxcontext
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
128 if False and delta > 0:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
129 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
130 return number, lines
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 self.header = header
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
133 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
134 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
135 self.proc = proc
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
136 self.hunk = hunk
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
137 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
138
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
139 def write(self, fp):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
140 delta = len(self.before) + len(self.after)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
141 fromlen = delta + self.removed
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
142 tolen = delta + self.added
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
143 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
144 (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
145 self.proc and (' ' + self.proc)))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
146 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
147
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
148 pretty = write
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
149
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
150 def filename(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
151 return self.header.filename()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
152
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
153 def __repr__(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
154 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
155
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
156 def parsepatch(fp):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
157 class parser(object):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
158 def __init__(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
159 self.fromline = 0
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
160 self.toline = 0
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
161 self.proc = ''
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
162 self.header = None
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
163 self.context = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
164 self.before = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
165 self.hunk = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
166 self.stream = []
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 addrange(self, (fromstart, fromend, tostart, toend, proc)):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
169 self.fromline = int(fromstart)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
170 self.toline = int(tostart)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
171 self.proc = proc
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
172
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
173 def addcontext(self, context):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
174 if self.hunk:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
175 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
176 self.before, self.hunk, context)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
177 self.header.hunks.append(h)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
178 self.stream.append(h)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
179 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
180 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
181 self.before = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
182 self.hunk = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
183 self.proc = ''
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
184 self.context = context
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
185
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
186 def addhunk(self, hunk):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
187 if self.context:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
188 self.before = self.context
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
189 self.context = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
190 self.hunk = data
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
191
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
192 def newfile(self, hdr):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
193 self.addcontext([])
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
194 h = header(hdr)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
195 self.stream.append(h)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
196 self.header = h
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
197
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
198 def finished(self):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
199 self.addcontext([])
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
200 return self.stream
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
201
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
202 transitions = {
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
203 'file': {'context': addcontext,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
204 'file': newfile,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
205 'hunk': addhunk,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
206 'range': addrange},
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
207 'context': {'file': newfile,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
208 'hunk': addhunk,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
209 'range': addrange},
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
210 'hunk': {'context': addcontext,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
211 'file': newfile,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
212 'range': addrange},
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
213 'range': {'context': addcontext,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
214 'hunk': addhunk},
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
215 }
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
216
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
217 p = parser()
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 state = 'context'
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
220 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
221 try:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
222 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
223 except KeyError:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
224 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
225 (state, newstate))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
226 state = newstate
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
227 return p.finished()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
228
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
229 def filterpatch(ui, chunks):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
230 chunks = list(chunks)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
231 chunks.reverse()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
232 seen = {}
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
233 def consumefile():
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
234 consumed = []
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
235 while chunks:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
236 if isinstance(chunks[-1], header):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
237 break
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
238 else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
239 consumed.append(chunks.pop())
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
240 return consumed
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
241 resp = None
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
242 applied = {}
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
243 while chunks:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
244 chunk = chunks.pop()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
245 if isinstance(chunk, header):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
246 fixoffset = 0
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
247 hdr = ''.join(chunk.header)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
248 if hdr in seen:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
249 consumefile()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
250 continue
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
251 seen[hdr] = True
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
252 if not resp:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
253 chunk.pretty(ui)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
254 r = resp or ui.prompt(_('record changes to %s? [y]es [n]o') %
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
255 _(' and ').join(map(repr, chunk.files())),
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
256 '(?:|[yYnNqQaA])$') or 'y'
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
257 if r in 'aA':
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
258 r = 'y'
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
259 resp = 'y'
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
260 if r in 'qQ':
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
261 raise util.Abort(_('user quit'))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
262 if r in 'yY':
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
263 applied[chunk.filename()] = [chunk]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
264 if chunk.allhunks():
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
265 applied[chunk.filename()] += consumefile()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
266 else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
267 consumefile()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
268 else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
269 if not resp:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
270 chunk.pretty(ui)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
271 r = resp or ui.prompt(_('record this change to %r? [y]es [n]o') %
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
272 chunk.filename(), '(?:|[yYnNqQaA])$') or 'y'
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
273 if r in 'aA':
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
274 r = 'y'
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
275 resp = 'y'
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
276 if r in 'qQ':
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
277 raise util.Abort(_('user quit'))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
278 if r in 'yY':
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
279 if fixoffset:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
280 chunk = copy.copy(chunk)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
281 chunk.toline += fixoffset
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
282 applied[chunk.filename()].append(chunk)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
283 else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
284 fixoffset += chunk.removed - chunk.added
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
285 return reduce(operator.add, [h for h in applied.itervalues()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
286 if h[0].special() or len(h) > 1], [])
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
287
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
288 def record(ui, repo, *pats, **opts):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
289 '''interactively select changes to commit'''
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
290
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
291 if not ui.interactive:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
292 raise util.Abort(_('running non-interactively, use commit instead'))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
293
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
294 def recordfunc(ui, repo, files, message, match, opts):
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
295 if files:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
296 changes = None
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
297 else:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
298 changes = repo.status(files=files, match=match)[:5]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
299 modified, added, removed = changes[:3]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
300 files = modified + added + removed
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
301 diffopts = mdiff.diffopts(git=True, nodates=True)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
302 fp = cStringIO.StringIO()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
303 patch.diff(repo, repo.dirstate.parents()[0], files=files,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
304 match=match, changes=changes, opts=diffopts, fp=fp)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
305 fp.seek(0)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
306
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
307 chunks = filterpatch(ui, parsepatch(fp))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
308 del fp
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
309
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
310 contenders = {}
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
311 for h in chunks:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
312 try: contenders.update(dict.fromkeys(h.files()))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
313 except AttributeError: pass
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
314
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
315 newfiles = [f for f in files if f in contenders]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
316
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
317 if not newfiles:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
318 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
319 return 0
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
320
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
321 if changes is None:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
322 changes = repo.status(files=newfiles, match=match)[:5]
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
323 modified = dict.fromkeys(changes[0])
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
324
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
325 backups = {}
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
326 backupdir = repo.join('record-backups')
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
327 try:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
328 os.mkdir(backupdir)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
329 except OSError, err:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
330 if err.errno == errno.EEXIST:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
331 pass
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
332 try:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
333 for f in newfiles:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
334 if f not in modified:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
335 continue
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
336 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
337 dir=backupdir)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
338 os.close(fd)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
339 ui.debug('backup %r as %r\n' % (f, tmpname))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
340 util.copyfile(repo.wjoin(f), tmpname)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
341 backups[f] = tmpname
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
342
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
343 fp = cStringIO.StringIO()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
344 for c in chunks:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
345 if c.filename() in backups:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
346 c.write(fp)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
347 dopatch = fp.tell()
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
348 fp.seek(0)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
349
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
350 if backups:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
351 hg.revert(repo, repo.dirstate.parents()[0], backups.has_key)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
352
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
353 if dopatch:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
354 ui.debug('applying patch\n')
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
355 ui.debug(fp.getvalue())
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
356 patch.internalpatch(fp, ui, 1, repo.root)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
357 del fp
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
358
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
359 repo.commit(newfiles, message, opts['user'], opts['date'], match,
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
360 force_editor=opts.get('force_editor'))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
361 return 0
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
362 finally:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
363 try:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
364 for realname, tmpname in backups.iteritems():
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
365 ui.debug('restoring %r to %r\n' % (tmpname, realname))
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
366 util.copyfile(tmpname, realname)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
367 os.unlink(tmpname)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
368 os.rmdir(backupdir)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
369 except OSError:
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
370 pass
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
371 return cmdutil.commit(ui, repo, recordfunc, pats, opts)
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
372
b2607267236d Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
373 cmdtable = {
5040
4f34d9b2568e Update style of record's cmdtable to match mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5037
diff changeset
374 "record":
4f34d9b2568e Update style of record's cmdtable to match mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5037
diff changeset
375 (record,
4f34d9b2568e Update style of record's cmdtable to match mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5037
diff changeset
376 [('A', 'addremove', None,
4f34d9b2568e Update style of record's cmdtable to match mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5037
diff changeset
377 _('mark new/missing files as added/removed before committing')),
4f34d9b2568e Update style of record's cmdtable to match mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5037
diff changeset
378 ('d', 'date', '', _('record datecode as commit date')),
4f34d9b2568e Update style of record's cmdtable to match mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5037
diff changeset
379 ('u', 'user', '', _('record user as commiter')),
4f34d9b2568e Update style of record's cmdtable to match mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5037
diff changeset
380 ] + commands.walkopts + commands.commitopts,
4f34d9b2568e Update style of record's cmdtable to match mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5037
diff changeset
381 _('hg record [OPTION]... [FILE]...')),
4f34d9b2568e Update style of record's cmdtable to match mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5037
diff changeset
382 }