Show More
@@ -15,9 +15,17 b' import copy, cStringIO, errno, operator,' | |||||
15 | lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)') |
|
15 | lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)') | |
16 |
|
16 | |||
17 | def scanpatch(fp): |
|
17 | def scanpatch(fp): | |
|
18 | """like patch.iterhunks, but yield different events | |||
|
19 | ||||
|
20 | - ('file', [header_lines + fromfile + tofile]) | |||
|
21 | - ('context', [context_lines]) | |||
|
22 | - ('hunk', [hunk_lines]) | |||
|
23 | - ('range', (-start,len, +start,len, diffp)) | |||
|
24 | """ | |||
18 | lr = patch.linereader(fp) |
|
25 | lr = patch.linereader(fp) | |
19 |
|
26 | |||
20 | def scanwhile(first, p): |
|
27 | def scanwhile(first, p): | |
|
28 | """scan lr while predicate holds""" | |||
21 | lines = [first] |
|
29 | lines = [first] | |
22 | while True: |
|
30 | while True: | |
23 | line = lr.readline() |
|
31 | line = lr.readline() | |
@@ -58,6 +66,10 b' def scanpatch(fp):' | |||||
58 | raise patch.PatchError('unknown patch content: %r' % line) |
|
66 | raise patch.PatchError('unknown patch content: %r' % line) | |
59 |
|
67 | |||
60 | class header(object): |
|
68 | class header(object): | |
|
69 | """patch header | |||
|
70 | ||||
|
71 | XXX shoudn't we move this to mercurial/patch.py ? | |||
|
72 | """ | |||
61 | diff_re = re.compile('diff --git a/(.*) b/(.*)$') |
|
73 | diff_re = re.compile('diff --git a/(.*) b/(.*)$') | |
62 | allhunks_re = re.compile('(?:index|new file|deleted file) ') |
|
74 | allhunks_re = re.compile('(?:index|new file|deleted file) ') | |
63 | pretty_re = re.compile('(?:new file|deleted file) ') |
|
75 | pretty_re = re.compile('(?:new file|deleted file) ') | |
@@ -115,11 +127,16 b' class header(object):' | |||||
115 | return True |
|
127 | return True | |
116 |
|
128 | |||
117 | def countchanges(hunk): |
|
129 | def countchanges(hunk): | |
|
130 | """hunk -> (n+,n-)""" | |||
118 | add = len([h for h in hunk if h[0] == '+']) |
|
131 | add = len([h for h in hunk if h[0] == '+']) | |
119 | rem = len([h for h in hunk if h[0] == '-']) |
|
132 | rem = len([h for h in hunk if h[0] == '-']) | |
120 | return add, rem |
|
133 | return add, rem | |
121 |
|
134 | |||
122 | class hunk(object): |
|
135 | class hunk(object): | |
|
136 | """patch hunk | |||
|
137 | ||||
|
138 | XXX shouldn't we merge this with patch.hunk ? | |||
|
139 | """ | |||
123 | maxcontext = 3 |
|
140 | maxcontext = 3 | |
124 |
|
141 | |||
125 | def __init__(self, header, fromline, toline, proc, before, hunk, after): |
|
142 | def __init__(self, header, fromline, toline, proc, before, hunk, after): | |
@@ -154,7 +171,9 b' class hunk(object):' | |||||
154 | return '<hunk %r@%d>' % (self.filename(), self.fromline) |
|
171 | return '<hunk %r@%d>' % (self.filename(), self.fromline) | |
155 |
|
172 | |||
156 | def parsepatch(fp): |
|
173 | def parsepatch(fp): | |
|
174 | """patch -> [] of hunks """ | |||
157 | class parser(object): |
|
175 | class parser(object): | |
|
176 | """patch parsing state machine""" | |||
158 | def __init__(self): |
|
177 | def __init__(self): | |
159 | self.fromline = 0 |
|
178 | self.fromline = 0 | |
160 | self.toline = 0 |
|
179 | self.toline = 0 | |
@@ -227,10 +246,14 b' def parsepatch(fp):' | |||||
227 | return p.finished() |
|
246 | return p.finished() | |
228 |
|
247 | |||
229 | def filterpatch(ui, chunks): |
|
248 | def filterpatch(ui, chunks): | |
|
249 | """Interactively filter patch chunks into applied-only chunks""" | |||
230 | chunks = list(chunks) |
|
250 | chunks = list(chunks) | |
231 | chunks.reverse() |
|
251 | chunks.reverse() | |
232 | seen = {} |
|
252 | seen = {} | |
233 | def consumefile(): |
|
253 | def consumefile(): | |
|
254 | """fetch next portion from chunks until a 'header' is seen | |||
|
255 | NB: header == new-file mark | |||
|
256 | """ | |||
234 | consumed = [] |
|
257 | consumed = [] | |
235 | while chunks: |
|
258 | while chunks: | |
236 | if isinstance(chunks[-1], header): |
|
259 | if isinstance(chunks[-1], header): | |
@@ -238,10 +261,20 b' def filterpatch(ui, chunks):' | |||||
238 | else: |
|
261 | else: | |
239 | consumed.append(chunks.pop()) |
|
262 | consumed.append(chunks.pop()) | |
240 | return consumed |
|
263 | return consumed | |
241 | resp_all = [None] |
|
264 | ||
242 | resp_file = [None] |
|
265 | resp_all = [None] # this two are changed from inside prompt, | |
243 | applied = {} |
|
266 | resp_file = [None] # so can't be usual variables | |
|
267 | applied = {} # 'filename' -> [] of chunks | |||
244 | def prompt(query): |
|
268 | def prompt(query): | |
|
269 | """prompt query, and process base inputs | |||
|
270 | ||||
|
271 | - y/n for the rest of file | |||
|
272 | - y/n for the rest | |||
|
273 | - ? (help) | |||
|
274 | - q (quit) | |||
|
275 | ||||
|
276 | else, input is returned to the caller. | |||
|
277 | """ | |||
245 | if resp_all[0] is not None: |
|
278 | if resp_all[0] is not None: | |
246 | return resp_all[0] |
|
279 | return resp_all[0] | |
247 | if resp_file[0] is not None: |
|
280 | if resp_file[0] is not None: | |
@@ -268,6 +301,7 b' def filterpatch(ui, chunks):' | |||||
268 | while chunks: |
|
301 | while chunks: | |
269 | chunk = chunks.pop() |
|
302 | chunk = chunks.pop() | |
270 | if isinstance(chunk, header): |
|
303 | if isinstance(chunk, header): | |
|
304 | # new-file mark | |||
271 | resp_file = [None] |
|
305 | resp_file = [None] | |
272 | fixoffset = 0 |
|
306 | fixoffset = 0 | |
273 | hdr = ''.join(chunk.header) |
|
307 | hdr = ''.join(chunk.header) | |
@@ -286,6 +320,7 b' def filterpatch(ui, chunks):' | |||||
286 | else: |
|
320 | else: | |
287 | consumefile() |
|
321 | consumefile() | |
288 | else: |
|
322 | else: | |
|
323 | # new hunk | |||
289 | if resp_file[0] is None and resp_all[0] is None: |
|
324 | if resp_file[0] is None and resp_all[0] is None: | |
290 | chunk.pretty(ui) |
|
325 | chunk.pretty(ui) | |
291 | r = prompt(_('record this change to %r?') % |
|
326 | r = prompt(_('record this change to %r?') % |
General Comments 0
You need to be logged in to leave comments.
Login now