##// END OF EJS Templates
record: some docs...
Kirill Smelkov -
r5826:cc43d9f3 default
parent child Browse files
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