236 if isinstance(chunks[-1], header): |
236 if isinstance(chunks[-1], header): |
237 break |
237 break |
238 else: |
238 else: |
239 consumed.append(chunks.pop()) |
239 consumed.append(chunks.pop()) |
240 return consumed |
240 return consumed |
241 resp = None |
241 resp_all = [None] |
|
242 resp_file = [None] |
242 applied = {} |
243 applied = {} |
|
244 def prompt(query): |
|
245 if resp_all[0] is not None: |
|
246 return resp_all[0] |
|
247 if resp_file[0] is not None: |
|
248 return resp_file[0] |
|
249 while True: |
|
250 r = (ui.prompt(query + _(' [Ynsfdaq?] '), '[Ynsfdaq?]?$', |
|
251 matchflags=re.I) or 'y').lower() |
|
252 if r == '?': |
|
253 c = record.__doc__.find('y - record this change') |
|
254 for l in record.__doc__[c:].splitlines(): |
|
255 if l: ui.write(_(l.strip()), '\n') |
|
256 continue |
|
257 elif r == 's': |
|
258 r = resp_file[0] = 'n' |
|
259 elif r == 'f': |
|
260 r = resp_file[0] = 'y' |
|
261 elif r == 'd': |
|
262 r = resp_all[0] = 'n' |
|
263 elif r == 'a': |
|
264 r = resp_all[0] = 'y' |
|
265 elif r == 'q': |
|
266 raise util.Abort(_('user quit')) |
|
267 return r |
243 while chunks: |
268 while chunks: |
244 chunk = chunks.pop() |
269 chunk = chunks.pop() |
245 if isinstance(chunk, header): |
270 if isinstance(chunk, header): |
|
271 resp_file = [None] |
246 fixoffset = 0 |
272 fixoffset = 0 |
247 hdr = ''.join(chunk.header) |
273 hdr = ''.join(chunk.header) |
248 if hdr in seen: |
274 if hdr in seen: |
249 consumefile() |
275 consumefile() |
250 continue |
276 continue |
251 seen[hdr] = True |
277 seen[hdr] = True |
252 if not resp: |
278 if resp_all[0] is None: |
253 chunk.pretty(ui) |
279 chunk.pretty(ui) |
254 r = resp or ui.prompt(_('record changes to %s? [y]es [n]o') % |
280 r = prompt(_('record changes to %s?') % |
255 _(' and ').join(map(repr, chunk.files())), |
281 _(' and ').join(map(repr, chunk.files()))) |
256 '(?:|[yYnNqQaA])$') or 'y' |
282 if r == 'y': |
257 if r in 'aA': |
|
258 r = 'y' |
|
259 resp = 'y' |
|
260 if r in 'qQ': |
|
261 raise util.Abort(_('user quit')) |
|
262 if r in 'yY': |
|
263 applied[chunk.filename()] = [chunk] |
283 applied[chunk.filename()] = [chunk] |
264 if chunk.allhunks(): |
284 if chunk.allhunks(): |
265 applied[chunk.filename()] += consumefile() |
285 applied[chunk.filename()] += consumefile() |
266 else: |
286 else: |
267 consumefile() |
287 consumefile() |
268 else: |
288 else: |
269 if not resp: |
289 if resp_file[0] is None and resp_all[0] is None: |
270 chunk.pretty(ui) |
290 chunk.pretty(ui) |
271 r = resp or ui.prompt(_('record this change to %r? [y]es [n]o') % |
291 r = prompt(_('record this change to %r?') % |
272 chunk.filename(), '(?:|[yYnNqQaA])$') or 'y' |
292 chunk.filename()) |
273 if r in 'aA': |
293 if r == 'y': |
274 r = 'y' |
|
275 resp = 'y' |
|
276 if r in 'qQ': |
|
277 raise util.Abort(_('user quit')) |
|
278 if r in 'yY': |
|
279 if fixoffset: |
294 if fixoffset: |
280 chunk = copy.copy(chunk) |
295 chunk = copy.copy(chunk) |
281 chunk.toline += fixoffset |
296 chunk.toline += fixoffset |
282 applied[chunk.filename()].append(chunk) |
297 applied[chunk.filename()].append(chunk) |
283 else: |
298 else: |
284 fixoffset += chunk.removed - chunk.added |
299 fixoffset += chunk.removed - chunk.added |
285 return reduce(operator.add, [h for h in applied.itervalues() |
300 return reduce(operator.add, [h for h in applied.itervalues() |
286 if h[0].special() or len(h) > 1], []) |
301 if h[0].special() or len(h) > 1], []) |
287 |
302 |
288 def record(ui, repo, *pats, **opts): |
303 def record(ui, repo, *pats, **opts): |
289 '''interactively select changes to commit''' |
304 '''interactively select changes to commit |
|
305 |
|
306 If a list of files is omitted, all changes reported by "hg status" |
|
307 will be candidates for recording. |
|
308 |
|
309 You will be prompted for whether to record changes to each |
|
310 modified file, and for files with multiple changes, for each |
|
311 change to use. For each query, the following responses are |
|
312 possible: |
|
313 |
|
314 y - record this change |
|
315 n - skip this change |
|
316 |
|
317 s - skip remaining changes to this file |
|
318 f - record remaining changes to this file |
|
319 |
|
320 d - done, skip remaining changes and files |
|
321 a - record all changes to all remaining files |
|
322 q - quit, recording no changes |
|
323 |
|
324 ? - display help''' |
290 |
325 |
291 if not ui.interactive: |
326 if not ui.interactive: |
292 raise util.Abort(_('running non-interactively, use commit instead')) |
327 raise util.Abort(_('running non-interactively, use commit instead')) |
293 |
328 |
294 def recordfunc(ui, repo, files, message, match, opts): |
329 def recordfunc(ui, repo, files, message, match, opts): |