##// END OF EJS Templates
record: use "ui.extractchoices()" to get the list of available responses...
FUJIWARA Katsunori -
r20266:06176632 default
parent child Browse files
Show More
@@ -1,682 +1,679 b''
1 1 # record.py
2 2 #
3 3 # Copyright 2007 Bryan O'Sullivan <bos@serpentine.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 '''commands to interactively select changes for commit/qrefresh'''
9 9
10 from mercurial.i18n import gettext, _
10 from mercurial.i18n import _
11 11 from mercurial import cmdutil, commands, extensions, hg, patch
12 12 from mercurial import util
13 13 import copy, cStringIO, errno, os, re, shutil, tempfile
14 14
15 15 cmdtable = {}
16 16 command = cmdutil.command(cmdtable)
17 17 testedwith = 'internal'
18 18
19 19 lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
20 20
21 21 diffopts = [
22 22 ('w', 'ignore-all-space', False,
23 23 _('ignore white space when comparing lines')),
24 24 ('b', 'ignore-space-change', None,
25 25 _('ignore changes in the amount of white space')),
26 26 ('B', 'ignore-blank-lines', None,
27 27 _('ignore changes whose lines are all blank')),
28 28 ]
29 29
30 30 def scanpatch(fp):
31 31 """like patch.iterhunks, but yield different events
32 32
33 33 - ('file', [header_lines + fromfile + tofile])
34 34 - ('context', [context_lines])
35 35 - ('hunk', [hunk_lines])
36 36 - ('range', (-start,len, +start,len, proc))
37 37 """
38 38 lr = patch.linereader(fp)
39 39
40 40 def scanwhile(first, p):
41 41 """scan lr while predicate holds"""
42 42 lines = [first]
43 43 while True:
44 44 line = lr.readline()
45 45 if not line:
46 46 break
47 47 if p(line):
48 48 lines.append(line)
49 49 else:
50 50 lr.push(line)
51 51 break
52 52 return lines
53 53
54 54 while True:
55 55 line = lr.readline()
56 56 if not line:
57 57 break
58 58 if line.startswith('diff --git a/') or line.startswith('diff -r '):
59 59 def notheader(line):
60 60 s = line.split(None, 1)
61 61 return not s or s[0] not in ('---', 'diff')
62 62 header = scanwhile(line, notheader)
63 63 fromfile = lr.readline()
64 64 if fromfile.startswith('---'):
65 65 tofile = lr.readline()
66 66 header += [fromfile, tofile]
67 67 else:
68 68 lr.push(fromfile)
69 69 yield 'file', header
70 70 elif line[0] == ' ':
71 71 yield 'context', scanwhile(line, lambda l: l[0] in ' \\')
72 72 elif line[0] in '-+':
73 73 yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\')
74 74 else:
75 75 m = lines_re.match(line)
76 76 if m:
77 77 yield 'range', m.groups()
78 78 else:
79 79 yield 'other', line
80 80
81 81 class header(object):
82 82 """patch header
83 83
84 84 XXX shouldn't we move this to mercurial/patch.py ?
85 85 """
86 86 diffgit_re = re.compile('diff --git a/(.*) b/(.*)$')
87 87 diff_re = re.compile('diff -r .* (.*)$')
88 88 allhunks_re = re.compile('(?:index|new file|deleted file) ')
89 89 pretty_re = re.compile('(?:new file|deleted file) ')
90 90 special_re = re.compile('(?:index|new|deleted|copy|rename) ')
91 91
92 92 def __init__(self, header):
93 93 self.header = header
94 94 self.hunks = []
95 95
96 96 def binary(self):
97 97 return util.any(h.startswith('index ') for h in self.header)
98 98
99 99 def pretty(self, fp):
100 100 for h in self.header:
101 101 if h.startswith('index '):
102 102 fp.write(_('this modifies a binary file (all or nothing)\n'))
103 103 break
104 104 if self.pretty_re.match(h):
105 105 fp.write(h)
106 106 if self.binary():
107 107 fp.write(_('this is a binary file\n'))
108 108 break
109 109 if h.startswith('---'):
110 110 fp.write(_('%d hunks, %d lines changed\n') %
111 111 (len(self.hunks),
112 112 sum([max(h.added, h.removed) for h in self.hunks])))
113 113 break
114 114 fp.write(h)
115 115
116 116 def write(self, fp):
117 117 fp.write(''.join(self.header))
118 118
119 119 def allhunks(self):
120 120 return util.any(self.allhunks_re.match(h) for h in self.header)
121 121
122 122 def files(self):
123 123 match = self.diffgit_re.match(self.header[0])
124 124 if match:
125 125 fromfile, tofile = match.groups()
126 126 if fromfile == tofile:
127 127 return [fromfile]
128 128 return [fromfile, tofile]
129 129 else:
130 130 return self.diff_re.match(self.header[0]).groups()
131 131
132 132 def filename(self):
133 133 return self.files()[-1]
134 134
135 135 def __repr__(self):
136 136 return '<header %s>' % (' '.join(map(repr, self.files())))
137 137
138 138 def special(self):
139 139 return util.any(self.special_re.match(h) for h in self.header)
140 140
141 141 def countchanges(hunk):
142 142 """hunk -> (n+,n-)"""
143 143 add = len([h for h in hunk if h[0] == '+'])
144 144 rem = len([h for h in hunk if h[0] == '-'])
145 145 return add, rem
146 146
147 147 class hunk(object):
148 148 """patch hunk
149 149
150 150 XXX shouldn't we merge this with patch.hunk ?
151 151 """
152 152 maxcontext = 3
153 153
154 154 def __init__(self, header, fromline, toline, proc, before, hunk, after):
155 155 def trimcontext(number, lines):
156 156 delta = len(lines) - self.maxcontext
157 157 if False and delta > 0:
158 158 return number + delta, lines[:self.maxcontext]
159 159 return number, lines
160 160
161 161 self.header = header
162 162 self.fromline, self.before = trimcontext(fromline, before)
163 163 self.toline, self.after = trimcontext(toline, after)
164 164 self.proc = proc
165 165 self.hunk = hunk
166 166 self.added, self.removed = countchanges(self.hunk)
167 167
168 168 def write(self, fp):
169 169 delta = len(self.before) + len(self.after)
170 170 if self.after and self.after[-1] == '\\ No newline at end of file\n':
171 171 delta -= 1
172 172 fromlen = delta + self.removed
173 173 tolen = delta + self.added
174 174 fp.write('@@ -%d,%d +%d,%d @@%s\n' %
175 175 (self.fromline, fromlen, self.toline, tolen,
176 176 self.proc and (' ' + self.proc)))
177 177 fp.write(''.join(self.before + self.hunk + self.after))
178 178
179 179 pretty = write
180 180
181 181 def filename(self):
182 182 return self.header.filename()
183 183
184 184 def __repr__(self):
185 185 return '<hunk %r@%d>' % (self.filename(), self.fromline)
186 186
187 187 def parsepatch(fp):
188 188 """patch -> [] of headers -> [] of hunks """
189 189 class parser(object):
190 190 """patch parsing state machine"""
191 191 def __init__(self):
192 192 self.fromline = 0
193 193 self.toline = 0
194 194 self.proc = ''
195 195 self.header = None
196 196 self.context = []
197 197 self.before = []
198 198 self.hunk = []
199 199 self.headers = []
200 200
201 201 def addrange(self, limits):
202 202 fromstart, fromend, tostart, toend, proc = limits
203 203 self.fromline = int(fromstart)
204 204 self.toline = int(tostart)
205 205 self.proc = proc
206 206
207 207 def addcontext(self, context):
208 208 if self.hunk:
209 209 h = hunk(self.header, self.fromline, self.toline, self.proc,
210 210 self.before, self.hunk, context)
211 211 self.header.hunks.append(h)
212 212 self.fromline += len(self.before) + h.removed
213 213 self.toline += len(self.before) + h.added
214 214 self.before = []
215 215 self.hunk = []
216 216 self.proc = ''
217 217 self.context = context
218 218
219 219 def addhunk(self, hunk):
220 220 if self.context:
221 221 self.before = self.context
222 222 self.context = []
223 223 self.hunk = hunk
224 224
225 225 def newfile(self, hdr):
226 226 self.addcontext([])
227 227 h = header(hdr)
228 228 self.headers.append(h)
229 229 self.header = h
230 230
231 231 def addother(self, line):
232 232 pass # 'other' lines are ignored
233 233
234 234 def finished(self):
235 235 self.addcontext([])
236 236 return self.headers
237 237
238 238 transitions = {
239 239 'file': {'context': addcontext,
240 240 'file': newfile,
241 241 'hunk': addhunk,
242 242 'range': addrange},
243 243 'context': {'file': newfile,
244 244 'hunk': addhunk,
245 245 'range': addrange,
246 246 'other': addother},
247 247 'hunk': {'context': addcontext,
248 248 'file': newfile,
249 249 'range': addrange},
250 250 'range': {'context': addcontext,
251 251 'hunk': addhunk},
252 252 'other': {'other': addother},
253 253 }
254 254
255 255 p = parser()
256 256
257 257 state = 'context'
258 258 for newstate, data in scanpatch(fp):
259 259 try:
260 260 p.transitions[state][newstate](p, data)
261 261 except KeyError:
262 262 raise patch.PatchError('unhandled transition: %s -> %s' %
263 263 (state, newstate))
264 264 state = newstate
265 265 return p.finished()
266 266
267 267 def filterpatch(ui, headers):
268 268 """Interactively filter patch chunks into applied-only chunks"""
269 269
270 270 def prompt(skipfile, skipall, query, chunk):
271 271 """prompt query, and process base inputs
272 272
273 273 - y/n for the rest of file
274 274 - y/n for the rest
275 275 - ? (help)
276 276 - q (quit)
277 277
278 278 Return True/False and possibly updated skipfile and skipall.
279 279 """
280 280 newpatches = None
281 281 if skipall is not None:
282 282 return skipall, skipfile, skipall, newpatches
283 283 if skipfile is not None:
284 284 return skipfile, skipfile, skipall, newpatches
285 285 while True:
286 286 resps = _('[Ynesfdaq?]'
287 287 '$$ &Yes, record this change'
288 288 '$$ &No, skip this change'
289 '$$ &Edit the change manually'
289 '$$ &Edit this change manually'
290 290 '$$ &Skip remaining changes to this file'
291 291 '$$ Record remaining changes to this &file'
292 292 '$$ &Done, skip remaining changes and files'
293 293 '$$ Record &all changes to all remaining files'
294 294 '$$ &Quit, recording no changes'
295 '$$ &?')
295 '$$ &? (display help)')
296 296 r = ui.promptchoice("%s %s" % (query, resps))
297 297 ui.write("\n")
298 298 if r == 8: # ?
299 doc = gettext(record.__doc__)
300 c = doc.find('::') + 2
301 for l in doc[c:].splitlines():
302 if l.startswith(' '):
303 ui.write(l.strip(), '\n')
299 for c, t in ui.extractchoices(resps)[1]:
300 ui.write('%s - %s\n' % (c, t.lower()))
304 301 continue
305 302 elif r == 0: # yes
306 303 ret = True
307 304 elif r == 1: # no
308 305 ret = False
309 306 elif r == 2: # Edit patch
310 307 if chunk is None:
311 308 ui.write(_('cannot edit patch for whole file'))
312 309 ui.write("\n")
313 310 continue
314 311 if chunk.header.binary():
315 312 ui.write(_('cannot edit patch for binary file'))
316 313 ui.write("\n")
317 314 continue
318 315 # Patch comment based on the Git one (based on comment at end of
319 316 # http://mercurial.selenic.com/wiki/RecordExtension)
320 317 phelp = '---' + _("""
321 318 To remove '-' lines, make them ' ' lines (context).
322 319 To remove '+' lines, delete them.
323 320 Lines starting with # will be removed from the patch.
324 321
325 322 If the patch applies cleanly, the edited hunk will immediately be
326 323 added to the record list. If it does not apply cleanly, a rejects
327 324 file will be generated: you can use that when you try again. If
328 325 all lines of the hunk are removed, then the edit is aborted and
329 326 the hunk is left unchanged.
330 327 """)
331 328 (patchfd, patchfn) = tempfile.mkstemp(prefix="hg-editor-",
332 329 suffix=".diff", text=True)
333 330 ncpatchfp = None
334 331 try:
335 332 # Write the initial patch
336 333 f = os.fdopen(patchfd, "w")
337 334 chunk.header.write(f)
338 335 chunk.write(f)
339 336 f.write('\n'.join(['# ' + i for i in phelp.splitlines()]))
340 337 f.close()
341 338 # Start the editor and wait for it to complete
342 339 editor = ui.geteditor()
343 340 util.system("%s \"%s\"" % (editor, patchfn),
344 341 environ={'HGUSER': ui.username()},
345 342 onerr=util.Abort, errprefix=_("edit failed"),
346 343 out=ui.fout)
347 344 # Remove comment lines
348 345 patchfp = open(patchfn)
349 346 ncpatchfp = cStringIO.StringIO()
350 347 for line in patchfp:
351 348 if not line.startswith('#'):
352 349 ncpatchfp.write(line)
353 350 patchfp.close()
354 351 ncpatchfp.seek(0)
355 352 newpatches = parsepatch(ncpatchfp)
356 353 finally:
357 354 os.unlink(patchfn)
358 355 del ncpatchfp
359 356 # Signal that the chunk shouldn't be applied as-is, but
360 357 # provide the new patch to be used instead.
361 358 ret = False
362 359 elif r == 3: # Skip
363 360 ret = skipfile = False
364 361 elif r == 4: # file (Record remaining)
365 362 ret = skipfile = True
366 363 elif r == 5: # done, skip remaining
367 364 ret = skipall = False
368 365 elif r == 6: # all
369 366 ret = skipall = True
370 367 elif r == 7: # quit
371 368 raise util.Abort(_('user quit'))
372 369 return ret, skipfile, skipall, newpatches
373 370
374 371 seen = set()
375 372 applied = {} # 'filename' -> [] of chunks
376 373 skipfile, skipall = None, None
377 374 pos, total = 1, sum(len(h.hunks) for h in headers)
378 375 for h in headers:
379 376 pos += len(h.hunks)
380 377 skipfile = None
381 378 fixoffset = 0
382 379 hdr = ''.join(h.header)
383 380 if hdr in seen:
384 381 continue
385 382 seen.add(hdr)
386 383 if skipall is None:
387 384 h.pretty(ui)
388 385 msg = (_('examine changes to %s?') %
389 386 _(' and ').join("'%s'" % f for f in h.files()))
390 387 r, skipfile, skipall, np = prompt(skipfile, skipall, msg, None)
391 388 if not r:
392 389 continue
393 390 applied[h.filename()] = [h]
394 391 if h.allhunks():
395 392 applied[h.filename()] += h.hunks
396 393 continue
397 394 for i, chunk in enumerate(h.hunks):
398 395 if skipfile is None and skipall is None:
399 396 chunk.pretty(ui)
400 397 if total == 1:
401 398 msg = _("record this change to '%s'?") % chunk.filename()
402 399 else:
403 400 idx = pos - len(h.hunks) + i
404 401 msg = _("record change %d/%d to '%s'?") % (idx, total,
405 402 chunk.filename())
406 403 r, skipfile, skipall, newpatches = prompt(skipfile,
407 404 skipall, msg, chunk)
408 405 if r:
409 406 if fixoffset:
410 407 chunk = copy.copy(chunk)
411 408 chunk.toline += fixoffset
412 409 applied[chunk.filename()].append(chunk)
413 410 elif newpatches is not None:
414 411 for newpatch in newpatches:
415 412 for newhunk in newpatch.hunks:
416 413 if fixoffset:
417 414 newhunk.toline += fixoffset
418 415 applied[newhunk.filename()].append(newhunk)
419 416 else:
420 417 fixoffset += chunk.removed - chunk.added
421 418 return sum([h for h in applied.itervalues()
422 419 if h[0].special() or len(h) > 1], [])
423 420
424 421 @command("record",
425 422 # same options as commit + white space diff options
426 423 commands.table['^commit|ci'][1][:] + diffopts,
427 424 _('hg record [OPTION]... [FILE]...'))
428 425 def record(ui, repo, *pats, **opts):
429 426 '''interactively select changes to commit
430 427
431 428 If a list of files is omitted, all changes reported by :hg:`status`
432 429 will be candidates for recording.
433 430
434 431 See :hg:`help dates` for a list of formats valid for -d/--date.
435 432
436 433 You will be prompted for whether to record changes to each
437 434 modified file, and for files with multiple changes, for each
438 435 change to use. For each query, the following responses are
439 436 possible::
440 437
441 438 y - record this change
442 439 n - skip this change
443 440 e - edit this change manually
444 441
445 442 s - skip remaining changes to this file
446 443 f - record remaining changes to this file
447 444
448 445 d - done, skip remaining changes and files
449 446 a - record all changes to all remaining files
450 447 q - quit, recording no changes
451 448
452 449 ? - display help
453 450
454 451 This command is not available when committing a merge.'''
455 452
456 453 dorecord(ui, repo, commands.commit, 'commit', False, *pats, **opts)
457 454
458 455 def qrefresh(origfn, ui, repo, *pats, **opts):
459 456 if not opts['interactive']:
460 457 return origfn(ui, repo, *pats, **opts)
461 458
462 459 mq = extensions.find('mq')
463 460
464 461 def committomq(ui, repo, *pats, **opts):
465 462 # At this point the working copy contains only changes that
466 463 # were accepted. All other changes were reverted.
467 464 # We can't pass *pats here since qrefresh will undo all other
468 465 # changed files in the patch that aren't in pats.
469 466 mq.refresh(ui, repo, **opts)
470 467
471 468 # backup all changed files
472 469 dorecord(ui, repo, committomq, 'qrefresh', True, *pats, **opts)
473 470
474 471 def qrecord(ui, repo, patch, *pats, **opts):
475 472 '''interactively record a new patch
476 473
477 474 See :hg:`help qnew` & :hg:`help record` for more information and
478 475 usage.
479 476 '''
480 477
481 478 try:
482 479 mq = extensions.find('mq')
483 480 except KeyError:
484 481 raise util.Abort(_("'mq' extension not loaded"))
485 482
486 483 repo.mq.checkpatchname(patch)
487 484
488 485 def committomq(ui, repo, *pats, **opts):
489 486 opts['checkname'] = False
490 487 mq.new(ui, repo, patch, *pats, **opts)
491 488
492 489 dorecord(ui, repo, committomq, 'qnew', False, *pats, **opts)
493 490
494 491 def qnew(origfn, ui, repo, patch, *args, **opts):
495 492 if opts['interactive']:
496 493 return qrecord(ui, repo, patch, *args, **opts)
497 494 return origfn(ui, repo, patch, *args, **opts)
498 495
499 496 def dorecord(ui, repo, commitfunc, cmdsuggest, backupall, *pats, **opts):
500 497 if not ui.interactive():
501 498 raise util.Abort(_('running non-interactively, use %s instead') %
502 499 cmdsuggest)
503 500
504 501 # make sure username is set before going interactive
505 502 if not opts.get('user'):
506 503 ui.username() # raise exception, username not provided
507 504
508 505 def recordfunc(ui, repo, message, match, opts):
509 506 """This is generic record driver.
510 507
511 508 Its job is to interactively filter local changes, and
512 509 accordingly prepare working directory into a state in which the
513 510 job can be delegated to a non-interactive commit command such as
514 511 'commit' or 'qrefresh'.
515 512
516 513 After the actual job is done by non-interactive command, the
517 514 working directory is restored to its original state.
518 515
519 516 In the end we'll record interesting changes, and everything else
520 517 will be left in place, so the user can continue working.
521 518 """
522 519
523 520 cmdutil.checkunfinished(repo, commit=True)
524 521 merge = len(repo[None].parents()) > 1
525 522 if merge:
526 523 raise util.Abort(_('cannot partially commit a merge '
527 524 '(use "hg commit" instead)'))
528 525
529 526 changes = repo.status(match=match)[:3]
530 527 diffopts = patch.diffopts(ui, opts=dict(
531 528 git=True, nodates=True,
532 529 ignorews=opts.get('ignore_all_space'),
533 530 ignorewsamount=opts.get('ignore_space_change'),
534 531 ignoreblanklines=opts.get('ignore_blank_lines')))
535 532 chunks = patch.diff(repo, changes=changes, opts=diffopts)
536 533 fp = cStringIO.StringIO()
537 534 fp.write(''.join(chunks))
538 535 fp.seek(0)
539 536
540 537 # 1. filter patch, so we have intending-to apply subset of it
541 538 try:
542 539 chunks = filterpatch(ui, parsepatch(fp))
543 540 except patch.PatchError, err:
544 541 raise util.Abort(_('error parsing patch: %s') % err)
545 542
546 543 del fp
547 544
548 545 contenders = set()
549 546 for h in chunks:
550 547 try:
551 548 contenders.update(set(h.files()))
552 549 except AttributeError:
553 550 pass
554 551
555 552 changed = changes[0] + changes[1] + changes[2]
556 553 newfiles = [f for f in changed if f in contenders]
557 554 if not newfiles:
558 555 ui.status(_('no changes to record\n'))
559 556 return 0
560 557
561 558 modified = set(changes[0])
562 559
563 560 # 2. backup changed files, so we can restore them in the end
564 561 if backupall:
565 562 tobackup = changed
566 563 else:
567 564 tobackup = [f for f in newfiles if f in modified]
568 565
569 566 backups = {}
570 567 if tobackup:
571 568 backupdir = repo.join('record-backups')
572 569 try:
573 570 os.mkdir(backupdir)
574 571 except OSError, err:
575 572 if err.errno != errno.EEXIST:
576 573 raise
577 574 try:
578 575 # backup continues
579 576 for f in tobackup:
580 577 fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
581 578 dir=backupdir)
582 579 os.close(fd)
583 580 ui.debug('backup %r as %r\n' % (f, tmpname))
584 581 util.copyfile(repo.wjoin(f), tmpname)
585 582 shutil.copystat(repo.wjoin(f), tmpname)
586 583 backups[f] = tmpname
587 584
588 585 fp = cStringIO.StringIO()
589 586 for c in chunks:
590 587 if c.filename() in backups:
591 588 c.write(fp)
592 589 dopatch = fp.tell()
593 590 fp.seek(0)
594 591
595 592 # 3a. apply filtered patch to clean repo (clean)
596 593 if backups:
597 594 hg.revert(repo, repo.dirstate.p1(),
598 595 lambda key: key in backups)
599 596
600 597 # 3b. (apply)
601 598 if dopatch:
602 599 try:
603 600 ui.debug('applying patch\n')
604 601 ui.debug(fp.getvalue())
605 602 patch.internalpatch(ui, repo, fp, 1, eolmode=None)
606 603 except patch.PatchError, err:
607 604 raise util.Abort(str(err))
608 605 del fp
609 606
610 607 # 4. We prepared working directory according to filtered
611 608 # patch. Now is the time to delegate the job to
612 609 # commit/qrefresh or the like!
613 610
614 611 # it is important to first chdir to repo root -- we'll call
615 612 # a highlevel command with list of pathnames relative to
616 613 # repo root
617 614 cwd = os.getcwd()
618 615 os.chdir(repo.root)
619 616 try:
620 617 commitfunc(ui, repo, *newfiles, **opts)
621 618 finally:
622 619 os.chdir(cwd)
623 620
624 621 return 0
625 622 finally:
626 623 # 5. finally restore backed-up files
627 624 try:
628 625 for realname, tmpname in backups.iteritems():
629 626 ui.debug('restoring %r to %r\n' % (tmpname, realname))
630 627 util.copyfile(tmpname, repo.wjoin(realname))
631 628 # Our calls to copystat() here and above are a
632 629 # hack to trick any editors that have f open that
633 630 # we haven't modified them.
634 631 #
635 632 # Also note that this racy as an editor could
636 633 # notice the file's mtime before we've finished
637 634 # writing it.
638 635 shutil.copystat(tmpname, repo.wjoin(realname))
639 636 os.unlink(tmpname)
640 637 if tobackup:
641 638 os.rmdir(backupdir)
642 639 except OSError:
643 640 pass
644 641
645 642 # wrap ui.write so diff output can be labeled/colorized
646 643 def wrapwrite(orig, *args, **kw):
647 644 label = kw.pop('label', '')
648 645 for chunk, l in patch.difflabel(lambda: args):
649 646 orig(chunk, label=label + l)
650 647 oldwrite = ui.write
651 648 extensions.wrapfunction(ui, 'write', wrapwrite)
652 649 try:
653 650 return cmdutil.commit(ui, repo, recordfunc, pats, opts)
654 651 finally:
655 652 ui.write = oldwrite
656 653
657 654 cmdtable["qrecord"] = \
658 655 (qrecord, [], # placeholder until mq is available
659 656 _('hg qrecord [OPTION]... PATCH [FILE]...'))
660 657
661 658 def uisetup(ui):
662 659 try:
663 660 mq = extensions.find('mq')
664 661 except KeyError:
665 662 return
666 663
667 664 cmdtable["qrecord"] = \
668 665 (qrecord,
669 666 # same options as qnew, but copy them so we don't get
670 667 # -i/--interactive for qrecord and add white space diff options
671 668 mq.cmdtable['^qnew'][1][:] + diffopts,
672 669 _('hg qrecord [OPTION]... PATCH [FILE]...'))
673 670
674 671 _wrapcmd('qnew', mq.cmdtable, qnew, _("interactively record a new patch"))
675 672 _wrapcmd('qrefresh', mq.cmdtable, qrefresh,
676 673 _("interactively select changes to refresh"))
677 674
678 675 def _wrapcmd(cmd, table, wrapfn, msg):
679 676 entry = extensions.wrapcommand(table, cmd, wrapfn)
680 677 entry[1].append(('i', 'interactive', None, msg))
681 678
682 679 commands.inferrepo += " record qrecord"
@@ -1,1301 +1,1301 b''
1 1 Set up a repo
2 2
3 3 $ echo "[ui]" >> $HGRCPATH
4 4 $ echo "interactive=true" >> $HGRCPATH
5 5 $ echo "[extensions]" >> $HGRCPATH
6 6 $ echo "record=" >> $HGRCPATH
7 7
8 8 $ hg init a
9 9 $ cd a
10 10
11 11 Select no files
12 12
13 13 $ touch empty-rw
14 14 $ hg add empty-rw
15 15
16 16 $ hg record empty-rw<<EOF
17 17 > n
18 18 > EOF
19 19 diff --git a/empty-rw b/empty-rw
20 20 new file mode 100644
21 21 examine changes to 'empty-rw'? [Ynesfdaq?]
22 22 no changes to record
23 23
24 24 $ hg tip -p
25 25 changeset: -1:000000000000
26 26 tag: tip
27 27 user:
28 28 date: Thu Jan 01 00:00:00 1970 +0000
29 29
30 30
31 31
32 32 Select files but no hunks
33 33
34 34 $ hg record empty-rw<<EOF
35 35 > y
36 36 > n
37 37 > EOF
38 38 diff --git a/empty-rw b/empty-rw
39 39 new file mode 100644
40 40 examine changes to 'empty-rw'? [Ynesfdaq?]
41 41 abort: empty commit message
42 42 [255]
43 43
44 44 $ hg tip -p
45 45 changeset: -1:000000000000
46 46 tag: tip
47 47 user:
48 48 date: Thu Jan 01 00:00:00 1970 +0000
49 49
50 50
51 51
52 52 Record empty file
53 53
54 54 $ hg record -d '0 0' -m empty empty-rw<<EOF
55 55 > y
56 56 > y
57 57 > EOF
58 58 diff --git a/empty-rw b/empty-rw
59 59 new file mode 100644
60 60 examine changes to 'empty-rw'? [Ynesfdaq?]
61 61
62 62 $ hg tip -p
63 63 changeset: 0:c0708cf4e46e
64 64 tag: tip
65 65 user: test
66 66 date: Thu Jan 01 00:00:00 1970 +0000
67 67 summary: empty
68 68
69 69
70 70
71 71 Summary shows we updated to the new cset
72 72
73 73 $ hg summary
74 74 parent: 0:c0708cf4e46e tip
75 75 empty
76 76 branch: default
77 77 commit: (clean)
78 78 update: (current)
79 79
80 80 Rename empty file
81 81
82 82 $ hg mv empty-rw empty-rename
83 83 $ hg record -d '1 0' -m rename<<EOF
84 84 > y
85 85 > EOF
86 86 diff --git a/empty-rw b/empty-rename
87 87 rename from empty-rw
88 88 rename to empty-rename
89 89 examine changes to 'empty-rw' and 'empty-rename'? [Ynesfdaq?]
90 90
91 91 $ hg tip -p
92 92 changeset: 1:d695e8dcb197
93 93 tag: tip
94 94 user: test
95 95 date: Thu Jan 01 00:00:01 1970 +0000
96 96 summary: rename
97 97
98 98
99 99
100 100 Copy empty file
101 101
102 102 $ hg cp empty-rename empty-copy
103 103 $ hg record -d '2 0' -m copy<<EOF
104 104 > y
105 105 > EOF
106 106 diff --git a/empty-rename b/empty-copy
107 107 copy from empty-rename
108 108 copy to empty-copy
109 109 examine changes to 'empty-rename' and 'empty-copy'? [Ynesfdaq?]
110 110
111 111 $ hg tip -p
112 112 changeset: 2:1d4b90bea524
113 113 tag: tip
114 114 user: test
115 115 date: Thu Jan 01 00:00:02 1970 +0000
116 116 summary: copy
117 117
118 118
119 119
120 120 Delete empty file
121 121
122 122 $ hg rm empty-copy
123 123 $ hg record -d '3 0' -m delete<<EOF
124 124 > y
125 125 > EOF
126 126 diff --git a/empty-copy b/empty-copy
127 127 deleted file mode 100644
128 128 examine changes to 'empty-copy'? [Ynesfdaq?]
129 129
130 130 $ hg tip -p
131 131 changeset: 3:b39a238f01a1
132 132 tag: tip
133 133 user: test
134 134 date: Thu Jan 01 00:00:03 1970 +0000
135 135 summary: delete
136 136
137 137
138 138
139 139 Add binary file
140 140
141 141 $ hg bundle --base -2 tip.bundle
142 142 1 changesets found
143 143 $ hg add tip.bundle
144 144 $ hg record -d '4 0' -m binary<<EOF
145 145 > y
146 146 > EOF
147 147 diff --git a/tip.bundle b/tip.bundle
148 148 new file mode 100644
149 149 this is a binary file
150 150 examine changes to 'tip.bundle'? [Ynesfdaq?]
151 151
152 152 $ hg tip -p
153 153 changeset: 4:ad816da3711e
154 154 tag: tip
155 155 user: test
156 156 date: Thu Jan 01 00:00:04 1970 +0000
157 157 summary: binary
158 158
159 159 diff -r b39a238f01a1 -r ad816da3711e tip.bundle
160 160 Binary file tip.bundle has changed
161 161
162 162
163 163 Change binary file
164 164
165 165 $ hg bundle --base -2 tip.bundle
166 166 1 changesets found
167 167 $ hg record -d '5 0' -m binary-change<<EOF
168 168 > y
169 169 > EOF
170 170 diff --git a/tip.bundle b/tip.bundle
171 171 this modifies a binary file (all or nothing)
172 172 examine changes to 'tip.bundle'? [Ynesfdaq?]
173 173
174 174 $ hg tip -p
175 175 changeset: 5:dccd6f3eb485
176 176 tag: tip
177 177 user: test
178 178 date: Thu Jan 01 00:00:05 1970 +0000
179 179 summary: binary-change
180 180
181 181 diff -r ad816da3711e -r dccd6f3eb485 tip.bundle
182 182 Binary file tip.bundle has changed
183 183
184 184
185 185 Rename and change binary file
186 186
187 187 $ hg mv tip.bundle top.bundle
188 188 $ hg bundle --base -2 top.bundle
189 189 1 changesets found
190 190 $ hg record -d '6 0' -m binary-change-rename<<EOF
191 191 > y
192 192 > EOF
193 193 diff --git a/tip.bundle b/top.bundle
194 194 rename from tip.bundle
195 195 rename to top.bundle
196 196 this modifies a binary file (all or nothing)
197 197 examine changes to 'tip.bundle' and 'top.bundle'? [Ynesfdaq?]
198 198
199 199 $ hg tip -p
200 200 changeset: 6:7fa44105f5b3
201 201 tag: tip
202 202 user: test
203 203 date: Thu Jan 01 00:00:06 1970 +0000
204 204 summary: binary-change-rename
205 205
206 206 diff -r dccd6f3eb485 -r 7fa44105f5b3 tip.bundle
207 207 Binary file tip.bundle has changed
208 208 diff -r dccd6f3eb485 -r 7fa44105f5b3 top.bundle
209 209 Binary file top.bundle has changed
210 210
211 211
212 212 Add plain file
213 213
214 214 $ for i in 1 2 3 4 5 6 7 8 9 10; do
215 215 > echo $i >> plain
216 216 > done
217 217
218 218 $ hg add plain
219 219 $ hg record -d '7 0' -m plain plain<<EOF
220 220 > y
221 221 > y
222 222 > EOF
223 223 diff --git a/plain b/plain
224 224 new file mode 100644
225 225 examine changes to 'plain'? [Ynesfdaq?]
226 226
227 227 $ hg tip -p
228 228 changeset: 7:11fb457c1be4
229 229 tag: tip
230 230 user: test
231 231 date: Thu Jan 01 00:00:07 1970 +0000
232 232 summary: plain
233 233
234 234 diff -r 7fa44105f5b3 -r 11fb457c1be4 plain
235 235 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
236 236 +++ b/plain Thu Jan 01 00:00:07 1970 +0000
237 237 @@ -0,0 +1,10 @@
238 238 +1
239 239 +2
240 240 +3
241 241 +4
242 242 +5
243 243 +6
244 244 +7
245 245 +8
246 246 +9
247 247 +10
248 248
249 249 Modify end of plain file with username unset
250 250
251 251 $ echo 11 >> plain
252 252 $ unset HGUSER
253 253 $ hg record --config ui.username= -d '8 0' -m end plain
254 254 abort: no username supplied (see "hg help config")
255 255 [255]
256 256
257 257
258 258 Modify end of plain file, also test that diffopts are accounted for
259 259
260 260 $ HGUSER="test"
261 261 $ export HGUSER
262 262 $ hg record --config diff.showfunc=true -d '8 0' -m end plain <<EOF
263 263 > y
264 264 > y
265 265 > EOF
266 266 diff --git a/plain b/plain
267 267 1 hunks, 1 lines changed
268 268 examine changes to 'plain'? [Ynesfdaq?]
269 269 @@ -8,3 +8,4 @@ 7
270 270 8
271 271 9
272 272 10
273 273 +11
274 274 record this change to 'plain'? [Ynesfdaq?]
275 275
276 276 Modify end of plain file, no EOL
277 277
278 278 $ hg tip --template '{node}' >> plain
279 279 $ hg record -d '9 0' -m noeol plain <<EOF
280 280 > y
281 281 > y
282 282 > EOF
283 283 diff --git a/plain b/plain
284 284 1 hunks, 1 lines changed
285 285 examine changes to 'plain'? [Ynesfdaq?]
286 286 @@ -9,3 +9,4 @@
287 287 9
288 288 10
289 289 11
290 290 +7264f99c5f5ff3261504828afa4fb4d406c3af54
291 291 \ No newline at end of file
292 292 record this change to 'plain'? [Ynesfdaq?]
293 293
294 294 Modify end of plain file, add EOL
295 295
296 296 $ echo >> plain
297 297 $ echo 1 > plain2
298 298 $ hg add plain2
299 299 $ hg record -d '10 0' -m eol plain plain2 <<EOF
300 300 > y
301 301 > y
302 302 > y
303 303 > EOF
304 304 diff --git a/plain b/plain
305 305 1 hunks, 1 lines changed
306 306 examine changes to 'plain'? [Ynesfdaq?]
307 307 @@ -9,4 +9,4 @@
308 308 9
309 309 10
310 310 11
311 311 -7264f99c5f5ff3261504828afa4fb4d406c3af54
312 312 \ No newline at end of file
313 313 +7264f99c5f5ff3261504828afa4fb4d406c3af54
314 314 record change 1/2 to 'plain'? [Ynesfdaq?]
315 315 diff --git a/plain2 b/plain2
316 316 new file mode 100644
317 317 examine changes to 'plain2'? [Ynesfdaq?]
318 318
319 319 Modify beginning, trim end, record both, add another file to test
320 320 changes numbering
321 321
322 322 $ rm plain
323 323 $ for i in 2 2 3 4 5 6 7 8 9 10; do
324 324 > echo $i >> plain
325 325 > done
326 326 $ echo 2 >> plain2
327 327
328 328 $ hg record -d '10 0' -m begin-and-end plain plain2 <<EOF
329 329 > y
330 330 > y
331 331 > y
332 332 > y
333 333 > y
334 334 > EOF
335 335 diff --git a/plain b/plain
336 336 2 hunks, 3 lines changed
337 337 examine changes to 'plain'? [Ynesfdaq?]
338 338 @@ -1,4 +1,4 @@
339 339 -1
340 340 +2
341 341 2
342 342 3
343 343 4
344 344 record change 1/3 to 'plain'? [Ynesfdaq?]
345 345 @@ -8,5 +8,3 @@
346 346 8
347 347 9
348 348 10
349 349 -11
350 350 -7264f99c5f5ff3261504828afa4fb4d406c3af54
351 351 record change 2/3 to 'plain'? [Ynesfdaq?]
352 352 diff --git a/plain2 b/plain2
353 353 1 hunks, 1 lines changed
354 354 examine changes to 'plain2'? [Ynesfdaq?]
355 355 @@ -1,1 +1,2 @@
356 356 1
357 357 +2
358 358 record change 3/3 to 'plain2'? [Ynesfdaq?]
359 359
360 360 $ hg tip -p
361 361 changeset: 11:21df83db12b8
362 362 tag: tip
363 363 user: test
364 364 date: Thu Jan 01 00:00:10 1970 +0000
365 365 summary: begin-and-end
366 366
367 367 diff -r ddb8b281c3ff -r 21df83db12b8 plain
368 368 --- a/plain Thu Jan 01 00:00:10 1970 +0000
369 369 +++ b/plain Thu Jan 01 00:00:10 1970 +0000
370 370 @@ -1,4 +1,4 @@
371 371 -1
372 372 +2
373 373 2
374 374 3
375 375 4
376 376 @@ -8,5 +8,3 @@
377 377 8
378 378 9
379 379 10
380 380 -11
381 381 -7264f99c5f5ff3261504828afa4fb4d406c3af54
382 382 diff -r ddb8b281c3ff -r 21df83db12b8 plain2
383 383 --- a/plain2 Thu Jan 01 00:00:10 1970 +0000
384 384 +++ b/plain2 Thu Jan 01 00:00:10 1970 +0000
385 385 @@ -1,1 +1,2 @@
386 386 1
387 387 +2
388 388
389 389
390 390 Trim beginning, modify end
391 391
392 392 $ rm plain
393 393 > for i in 4 5 6 7 8 9 10.new; do
394 394 > echo $i >> plain
395 395 > done
396 396
397 397 Record end
398 398
399 399 $ hg record -d '11 0' -m end-only plain <<EOF
400 400 > y
401 401 > n
402 402 > y
403 403 > EOF
404 404 diff --git a/plain b/plain
405 405 2 hunks, 4 lines changed
406 406 examine changes to 'plain'? [Ynesfdaq?]
407 407 @@ -1,9 +1,6 @@
408 408 -2
409 409 -2
410 410 -3
411 411 4
412 412 5
413 413 6
414 414 7
415 415 8
416 416 9
417 417 record change 1/2 to 'plain'? [Ynesfdaq?]
418 418 @@ -4,7 +1,7 @@
419 419 4
420 420 5
421 421 6
422 422 7
423 423 8
424 424 9
425 425 -10
426 426 +10.new
427 427 record change 2/2 to 'plain'? [Ynesfdaq?]
428 428
429 429 $ hg tip -p
430 430 changeset: 12:99337501826f
431 431 tag: tip
432 432 user: test
433 433 date: Thu Jan 01 00:00:11 1970 +0000
434 434 summary: end-only
435 435
436 436 diff -r 21df83db12b8 -r 99337501826f plain
437 437 --- a/plain Thu Jan 01 00:00:10 1970 +0000
438 438 +++ b/plain Thu Jan 01 00:00:11 1970 +0000
439 439 @@ -7,4 +7,4 @@
440 440 7
441 441 8
442 442 9
443 443 -10
444 444 +10.new
445 445
446 446
447 447 Record beginning
448 448
449 449 $ hg record -d '12 0' -m begin-only plain <<EOF
450 450 > y
451 451 > y
452 452 > EOF
453 453 diff --git a/plain b/plain
454 454 1 hunks, 3 lines changed
455 455 examine changes to 'plain'? [Ynesfdaq?]
456 456 @@ -1,6 +1,3 @@
457 457 -2
458 458 -2
459 459 -3
460 460 4
461 461 5
462 462 6
463 463 record this change to 'plain'? [Ynesfdaq?]
464 464
465 465 $ hg tip -p
466 466 changeset: 13:bbd45465d540
467 467 tag: tip
468 468 user: test
469 469 date: Thu Jan 01 00:00:12 1970 +0000
470 470 summary: begin-only
471 471
472 472 diff -r 99337501826f -r bbd45465d540 plain
473 473 --- a/plain Thu Jan 01 00:00:11 1970 +0000
474 474 +++ b/plain Thu Jan 01 00:00:12 1970 +0000
475 475 @@ -1,6 +1,3 @@
476 476 -2
477 477 -2
478 478 -3
479 479 4
480 480 5
481 481 6
482 482
483 483
484 484 Add to beginning, trim from end
485 485
486 486 $ rm plain
487 487 $ for i in 1 2 3 4 5 6 7 8 9; do
488 488 > echo $i >> plain
489 489 > done
490 490
491 491 Record end
492 492
493 493 $ hg record --traceback -d '13 0' -m end-again plain<<EOF
494 494 > y
495 495 > n
496 496 > y
497 497 > EOF
498 498 diff --git a/plain b/plain
499 499 2 hunks, 4 lines changed
500 500 examine changes to 'plain'? [Ynesfdaq?]
501 501 @@ -1,6 +1,9 @@
502 502 +1
503 503 +2
504 504 +3
505 505 4
506 506 5
507 507 6
508 508 7
509 509 8
510 510 9
511 511 record change 1/2 to 'plain'? [Ynesfdaq?]
512 512 @@ -1,7 +4,6 @@
513 513 4
514 514 5
515 515 6
516 516 7
517 517 8
518 518 9
519 519 -10.new
520 520 record change 2/2 to 'plain'? [Ynesfdaq?]
521 521
522 522 Add to beginning, middle, end
523 523
524 524 $ rm plain
525 525 $ for i in 1 2 3 4 5 5.new 5.reallynew 6 7 8 9 10 11; do
526 526 > echo $i >> plain
527 527 > done
528 528
529 529 Record beginning, middle
530 530
531 531 $ hg record -d '14 0' -m middle-only plain <<EOF
532 532 > y
533 533 > y
534 534 > y
535 535 > n
536 536 > EOF
537 537 diff --git a/plain b/plain
538 538 3 hunks, 7 lines changed
539 539 examine changes to 'plain'? [Ynesfdaq?]
540 540 @@ -1,2 +1,5 @@
541 541 +1
542 542 +2
543 543 +3
544 544 4
545 545 5
546 546 record change 1/3 to 'plain'? [Ynesfdaq?]
547 547 @@ -1,6 +4,8 @@
548 548 4
549 549 5
550 550 +5.new
551 551 +5.reallynew
552 552 6
553 553 7
554 554 8
555 555 9
556 556 record change 2/3 to 'plain'? [Ynesfdaq?]
557 557 @@ -3,4 +8,6 @@
558 558 6
559 559 7
560 560 8
561 561 9
562 562 +10
563 563 +11
564 564 record change 3/3 to 'plain'? [Ynesfdaq?]
565 565
566 566 $ hg tip -p
567 567 changeset: 15:f34a7937ec33
568 568 tag: tip
569 569 user: test
570 570 date: Thu Jan 01 00:00:14 1970 +0000
571 571 summary: middle-only
572 572
573 573 diff -r 82c065d0b850 -r f34a7937ec33 plain
574 574 --- a/plain Thu Jan 01 00:00:13 1970 +0000
575 575 +++ b/plain Thu Jan 01 00:00:14 1970 +0000
576 576 @@ -1,5 +1,10 @@
577 577 +1
578 578 +2
579 579 +3
580 580 4
581 581 5
582 582 +5.new
583 583 +5.reallynew
584 584 6
585 585 7
586 586 8
587 587
588 588
589 589 Record end
590 590
591 591 $ hg record -d '15 0' -m end-only plain <<EOF
592 592 > y
593 593 > y
594 594 > EOF
595 595 diff --git a/plain b/plain
596 596 1 hunks, 2 lines changed
597 597 examine changes to 'plain'? [Ynesfdaq?]
598 598 @@ -9,3 +9,5 @@
599 599 7
600 600 8
601 601 9
602 602 +10
603 603 +11
604 604 record this change to 'plain'? [Ynesfdaq?]
605 605
606 606 $ hg tip -p
607 607 changeset: 16:f9900b71a04c
608 608 tag: tip
609 609 user: test
610 610 date: Thu Jan 01 00:00:15 1970 +0000
611 611 summary: end-only
612 612
613 613 diff -r f34a7937ec33 -r f9900b71a04c plain
614 614 --- a/plain Thu Jan 01 00:00:14 1970 +0000
615 615 +++ b/plain Thu Jan 01 00:00:15 1970 +0000
616 616 @@ -9,3 +9,5 @@
617 617 7
618 618 8
619 619 9
620 620 +10
621 621 +11
622 622
623 623
624 624 $ mkdir subdir
625 625 $ cd subdir
626 626 $ echo a > a
627 627 $ hg ci -d '16 0' -Amsubdir
628 628 adding subdir/a
629 629
630 630 $ echo a >> a
631 631 $ hg record -d '16 0' -m subdir-change a <<EOF
632 632 > y
633 633 > y
634 634 > EOF
635 635 diff --git a/subdir/a b/subdir/a
636 636 1 hunks, 1 lines changed
637 637 examine changes to 'subdir/a'? [Ynesfdaq?]
638 638 @@ -1,1 +1,2 @@
639 639 a
640 640 +a
641 641 record this change to 'subdir/a'? [Ynesfdaq?]
642 642
643 643 $ hg tip -p
644 644 changeset: 18:61be427a9deb
645 645 tag: tip
646 646 user: test
647 647 date: Thu Jan 01 00:00:16 1970 +0000
648 648 summary: subdir-change
649 649
650 650 diff -r a7ffae4d61cb -r 61be427a9deb subdir/a
651 651 --- a/subdir/a Thu Jan 01 00:00:16 1970 +0000
652 652 +++ b/subdir/a Thu Jan 01 00:00:16 1970 +0000
653 653 @@ -1,1 +1,2 @@
654 654 a
655 655 +a
656 656
657 657
658 658 $ echo a > f1
659 659 $ echo b > f2
660 660 $ hg add f1 f2
661 661
662 662 $ hg ci -mz -d '17 0'
663 663
664 664 $ echo a >> f1
665 665 $ echo b >> f2
666 666
667 667 Help, quit
668 668
669 669 $ hg record <<EOF
670 670 > ?
671 671 > q
672 672 > EOF
673 673 diff --git a/subdir/f1 b/subdir/f1
674 674 1 hunks, 1 lines changed
675 675 examine changes to 'subdir/f1'? [Ynesfdaq?]
676 y - record this change
677 n - skip this change
676 y - yes, record this change
677 n - no, skip this change
678 678 e - edit this change manually
679 679 s - skip remaining changes to this file
680 680 f - record remaining changes to this file
681 681 d - done, skip remaining changes and files
682 682 a - record all changes to all remaining files
683 683 q - quit, recording no changes
684 ? - display help
684 ? - ? (display help)
685 685 examine changes to 'subdir/f1'? [Ynesfdaq?]
686 686 abort: user quit
687 687 [255]
688 688
689 689 Skip
690 690
691 691 $ hg record <<EOF
692 692 > s
693 693 > EOF
694 694 diff --git a/subdir/f1 b/subdir/f1
695 695 1 hunks, 1 lines changed
696 696 examine changes to 'subdir/f1'? [Ynesfdaq?]
697 697 diff --git a/subdir/f2 b/subdir/f2
698 698 1 hunks, 1 lines changed
699 699 examine changes to 'subdir/f2'? [Ynesfdaq?] abort: response expected
700 700 [255]
701 701
702 702 No
703 703
704 704 $ hg record <<EOF
705 705 > n
706 706 > EOF
707 707 diff --git a/subdir/f1 b/subdir/f1
708 708 1 hunks, 1 lines changed
709 709 examine changes to 'subdir/f1'? [Ynesfdaq?]
710 710 diff --git a/subdir/f2 b/subdir/f2
711 711 1 hunks, 1 lines changed
712 712 examine changes to 'subdir/f2'? [Ynesfdaq?] abort: response expected
713 713 [255]
714 714
715 715 f, quit
716 716
717 717 $ hg record <<EOF
718 718 > f
719 719 > q
720 720 > EOF
721 721 diff --git a/subdir/f1 b/subdir/f1
722 722 1 hunks, 1 lines changed
723 723 examine changes to 'subdir/f1'? [Ynesfdaq?]
724 724 diff --git a/subdir/f2 b/subdir/f2
725 725 1 hunks, 1 lines changed
726 726 examine changes to 'subdir/f2'? [Ynesfdaq?]
727 727 abort: user quit
728 728 [255]
729 729
730 730 s, all
731 731
732 732 $ hg record -d '18 0' -mx <<EOF
733 733 > s
734 734 > a
735 735 > EOF
736 736 diff --git a/subdir/f1 b/subdir/f1
737 737 1 hunks, 1 lines changed
738 738 examine changes to 'subdir/f1'? [Ynesfdaq?]
739 739 diff --git a/subdir/f2 b/subdir/f2
740 740 1 hunks, 1 lines changed
741 741 examine changes to 'subdir/f2'? [Ynesfdaq?]
742 742
743 743 $ hg tip -p
744 744 changeset: 20:b3df3dda369a
745 745 tag: tip
746 746 user: test
747 747 date: Thu Jan 01 00:00:18 1970 +0000
748 748 summary: x
749 749
750 750 diff -r 6e02d6c9906d -r b3df3dda369a subdir/f2
751 751 --- a/subdir/f2 Thu Jan 01 00:00:17 1970 +0000
752 752 +++ b/subdir/f2 Thu Jan 01 00:00:18 1970 +0000
753 753 @@ -1,1 +1,2 @@
754 754 b
755 755 +b
756 756
757 757
758 758 f
759 759
760 760 $ hg record -d '19 0' -my <<EOF
761 761 > f
762 762 > EOF
763 763 diff --git a/subdir/f1 b/subdir/f1
764 764 1 hunks, 1 lines changed
765 765 examine changes to 'subdir/f1'? [Ynesfdaq?]
766 766
767 767 $ hg tip -p
768 768 changeset: 21:38ec577f126b
769 769 tag: tip
770 770 user: test
771 771 date: Thu Jan 01 00:00:19 1970 +0000
772 772 summary: y
773 773
774 774 diff -r b3df3dda369a -r 38ec577f126b subdir/f1
775 775 --- a/subdir/f1 Thu Jan 01 00:00:18 1970 +0000
776 776 +++ b/subdir/f1 Thu Jan 01 00:00:19 1970 +0000
777 777 @@ -1,1 +1,2 @@
778 778 a
779 779 +a
780 780
781 781
782 782 #if execbit
783 783
784 784 Preserve chmod +x
785 785
786 786 $ chmod +x f1
787 787 $ echo a >> f1
788 788 $ hg record -d '20 0' -mz <<EOF
789 789 > y
790 790 > y
791 791 > y
792 792 > EOF
793 793 diff --git a/subdir/f1 b/subdir/f1
794 794 old mode 100644
795 795 new mode 100755
796 796 1 hunks, 1 lines changed
797 797 examine changes to 'subdir/f1'? [Ynesfdaq?]
798 798 @@ -1,2 +1,3 @@
799 799 a
800 800 a
801 801 +a
802 802 record this change to 'subdir/f1'? [Ynesfdaq?]
803 803
804 804 $ hg tip --config diff.git=True -p
805 805 changeset: 22:3261adceb075
806 806 tag: tip
807 807 user: test
808 808 date: Thu Jan 01 00:00:20 1970 +0000
809 809 summary: z
810 810
811 811 diff --git a/subdir/f1 b/subdir/f1
812 812 old mode 100644
813 813 new mode 100755
814 814 --- a/subdir/f1
815 815 +++ b/subdir/f1
816 816 @@ -1,2 +1,3 @@
817 817 a
818 818 a
819 819 +a
820 820
821 821
822 822 Preserve execute permission on original
823 823
824 824 $ echo b >> f1
825 825 $ hg record -d '21 0' -maa <<EOF
826 826 > y
827 827 > y
828 828 > y
829 829 > EOF
830 830 diff --git a/subdir/f1 b/subdir/f1
831 831 1 hunks, 1 lines changed
832 832 examine changes to 'subdir/f1'? [Ynesfdaq?]
833 833 @@ -1,3 +1,4 @@
834 834 a
835 835 a
836 836 a
837 837 +b
838 838 record this change to 'subdir/f1'? [Ynesfdaq?]
839 839
840 840 $ hg tip --config diff.git=True -p
841 841 changeset: 23:b429867550db
842 842 tag: tip
843 843 user: test
844 844 date: Thu Jan 01 00:00:21 1970 +0000
845 845 summary: aa
846 846
847 847 diff --git a/subdir/f1 b/subdir/f1
848 848 --- a/subdir/f1
849 849 +++ b/subdir/f1
850 850 @@ -1,3 +1,4 @@
851 851 a
852 852 a
853 853 a
854 854 +b
855 855
856 856
857 857 Preserve chmod -x
858 858
859 859 $ chmod -x f1
860 860 $ echo c >> f1
861 861 $ hg record -d '22 0' -mab <<EOF
862 862 > y
863 863 > y
864 864 > y
865 865 > EOF
866 866 diff --git a/subdir/f1 b/subdir/f1
867 867 old mode 100755
868 868 new mode 100644
869 869 1 hunks, 1 lines changed
870 870 examine changes to 'subdir/f1'? [Ynesfdaq?]
871 871 @@ -2,3 +2,4 @@
872 872 a
873 873 a
874 874 b
875 875 +c
876 876 record this change to 'subdir/f1'? [Ynesfdaq?]
877 877
878 878 $ hg tip --config diff.git=True -p
879 879 changeset: 24:0b082130c20a
880 880 tag: tip
881 881 user: test
882 882 date: Thu Jan 01 00:00:22 1970 +0000
883 883 summary: ab
884 884
885 885 diff --git a/subdir/f1 b/subdir/f1
886 886 old mode 100755
887 887 new mode 100644
888 888 --- a/subdir/f1
889 889 +++ b/subdir/f1
890 890 @@ -2,3 +2,4 @@
891 891 a
892 892 a
893 893 b
894 894 +c
895 895
896 896
897 897 #else
898 898
899 899 Slightly bogus tests to get almost same repo structure as when x bit is used
900 900 - but with different hashes.
901 901
902 902 Mock "Preserve chmod +x"
903 903
904 904 $ echo a >> f1
905 905 $ hg record -d '20 0' -mz <<EOF
906 906 > y
907 907 > y
908 908 > y
909 909 > EOF
910 910 diff --git a/subdir/f1 b/subdir/f1
911 911 1 hunks, 1 lines changed
912 912 examine changes to 'subdir/f1'? [Ynesfdaq?]
913 913 @@ -1,2 +1,3 @@
914 914 a
915 915 a
916 916 +a
917 917 record this change to 'subdir/f1'? [Ynesfdaq?]
918 918
919 919 $ hg tip --config diff.git=True -p
920 920 changeset: 22:0d463bd428f5
921 921 tag: tip
922 922 user: test
923 923 date: Thu Jan 01 00:00:20 1970 +0000
924 924 summary: z
925 925
926 926 diff --git a/subdir/f1 b/subdir/f1
927 927 --- a/subdir/f1
928 928 +++ b/subdir/f1
929 929 @@ -1,2 +1,3 @@
930 930 a
931 931 a
932 932 +a
933 933
934 934
935 935 Mock "Preserve execute permission on original"
936 936
937 937 $ echo b >> f1
938 938 $ hg record -d '21 0' -maa <<EOF
939 939 > y
940 940 > y
941 941 > y
942 942 > EOF
943 943 diff --git a/subdir/f1 b/subdir/f1
944 944 1 hunks, 1 lines changed
945 945 examine changes to 'subdir/f1'? [Ynesfdaq?]
946 946 @@ -1,3 +1,4 @@
947 947 a
948 948 a
949 949 a
950 950 +b
951 951 record this change to 'subdir/f1'? [Ynesfdaq?]
952 952
953 953 $ hg tip --config diff.git=True -p
954 954 changeset: 23:0eab41a3e524
955 955 tag: tip
956 956 user: test
957 957 date: Thu Jan 01 00:00:21 1970 +0000
958 958 summary: aa
959 959
960 960 diff --git a/subdir/f1 b/subdir/f1
961 961 --- a/subdir/f1
962 962 +++ b/subdir/f1
963 963 @@ -1,3 +1,4 @@
964 964 a
965 965 a
966 966 a
967 967 +b
968 968
969 969
970 970 Mock "Preserve chmod -x"
971 971
972 972 $ chmod -x f1
973 973 $ echo c >> f1
974 974 $ hg record -d '22 0' -mab <<EOF
975 975 > y
976 976 > y
977 977 > y
978 978 > EOF
979 979 diff --git a/subdir/f1 b/subdir/f1
980 980 1 hunks, 1 lines changed
981 981 examine changes to 'subdir/f1'? [Ynesfdaq?]
982 982 @@ -2,3 +2,4 @@
983 983 a
984 984 a
985 985 b
986 986 +c
987 987 record this change to 'subdir/f1'? [Ynesfdaq?]
988 988
989 989 $ hg tip --config diff.git=True -p
990 990 changeset: 24:f4f718f27b7c
991 991 tag: tip
992 992 user: test
993 993 date: Thu Jan 01 00:00:22 1970 +0000
994 994 summary: ab
995 995
996 996 diff --git a/subdir/f1 b/subdir/f1
997 997 --- a/subdir/f1
998 998 +++ b/subdir/f1
999 999 @@ -2,3 +2,4 @@
1000 1000 a
1001 1001 a
1002 1002 b
1003 1003 +c
1004 1004
1005 1005
1006 1006 #endif
1007 1007
1008 1008 $ cd ..
1009 1009
1010 1010
1011 1011 Abort early when a merge is in progress
1012 1012
1013 1013 $ hg up 4
1014 1014 1 files updated, 0 files merged, 6 files removed, 0 files unresolved
1015 1015
1016 1016 $ touch iwillmergethat
1017 1017 $ hg add iwillmergethat
1018 1018
1019 1019 $ hg branch thatbranch
1020 1020 marked working directory as branch thatbranch
1021 1021 (branches are permanent and global, did you want a bookmark?)
1022 1022
1023 1023 $ hg ci -m'new head'
1024 1024
1025 1025 $ hg up default
1026 1026 6 files updated, 0 files merged, 2 files removed, 0 files unresolved
1027 1027
1028 1028 $ hg merge thatbranch
1029 1029 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1030 1030 (branch merge, don't forget to commit)
1031 1031
1032 1032 $ hg record -m'will abort'
1033 1033 abort: cannot partially commit a merge (use "hg commit" instead)
1034 1034 [255]
1035 1035
1036 1036 $ hg up -C
1037 1037 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1038 1038
1039 1039 Editing patch (and ignoring trailing text)
1040 1040
1041 1041 $ cat > editor.sh << '__EOF__'
1042 1042 > sed -e 7d -e '5s/^-/ /' -e '/^# ---/i\
1043 1043 > trailing\nditto' "$1" > tmp
1044 1044 > mv tmp "$1"
1045 1045 > __EOF__
1046 1046 $ cat > editedfile << '__EOF__'
1047 1047 > This is the first line
1048 1048 > This is the second line
1049 1049 > This is the third line
1050 1050 > __EOF__
1051 1051 $ hg add editedfile
1052 1052 $ hg commit -medit-patch-1
1053 1053 $ cat > editedfile << '__EOF__'
1054 1054 > This line has changed
1055 1055 > This change will be committed
1056 1056 > This is the third line
1057 1057 > __EOF__
1058 1058 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record -d '23 0' -medit-patch-2 <<EOF
1059 1059 > y
1060 1060 > e
1061 1061 > EOF
1062 1062 diff --git a/editedfile b/editedfile
1063 1063 1 hunks, 2 lines changed
1064 1064 examine changes to 'editedfile'? [Ynesfdaq?]
1065 1065 @@ -1,3 +1,3 @@
1066 1066 -This is the first line
1067 1067 -This is the second line
1068 1068 +This line has changed
1069 1069 +This change will be committed
1070 1070 This is the third line
1071 1071 record this change to 'editedfile'? [Ynesfdaq?]
1072 1072 $ cat editedfile
1073 1073 This line has changed
1074 1074 This change will be committed
1075 1075 This is the third line
1076 1076 $ hg cat -r tip editedfile
1077 1077 This is the first line
1078 1078 This change will be committed
1079 1079 This is the third line
1080 1080 $ hg revert editedfile
1081 1081
1082 1082 Trying to edit patch for whole file
1083 1083
1084 1084 $ echo "This is the fourth line" >> editedfile
1085 1085 $ hg record <<EOF
1086 1086 > e
1087 1087 > q
1088 1088 > EOF
1089 1089 diff --git a/editedfile b/editedfile
1090 1090 1 hunks, 1 lines changed
1091 1091 examine changes to 'editedfile'? [Ynesfdaq?]
1092 1092 cannot edit patch for whole file
1093 1093 examine changes to 'editedfile'? [Ynesfdaq?]
1094 1094 abort: user quit
1095 1095 [255]
1096 1096 $ hg revert editedfile
1097 1097
1098 1098 Removing changes from patch
1099 1099
1100 1100 $ sed -e '3s/third/second/' -e '2s/will/will not/' -e 1d editedfile > tmp
1101 1101 $ mv tmp editedfile
1102 1102 $ echo "This line has been added" >> editedfile
1103 1103 $ cat > editor.sh << '__EOF__'
1104 1104 > sed -e 's/^[-+]/ /' "$1" > tmp
1105 1105 > mv tmp "$1"
1106 1106 > __EOF__
1107 1107 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record <<EOF
1108 1108 > y
1109 1109 > e
1110 1110 > EOF
1111 1111 diff --git a/editedfile b/editedfile
1112 1112 1 hunks, 3 lines changed
1113 1113 examine changes to 'editedfile'? [Ynesfdaq?]
1114 1114 @@ -1,3 +1,3 @@
1115 1115 -This is the first line
1116 1116 -This change will be committed
1117 1117 -This is the third line
1118 1118 +This change will not be committed
1119 1119 +This is the second line
1120 1120 +This line has been added
1121 1121 record this change to 'editedfile'? [Ynesfdaq?]
1122 1122 no changes to record
1123 1123 $ cat editedfile
1124 1124 This change will not be committed
1125 1125 This is the second line
1126 1126 This line has been added
1127 1127 $ hg cat -r tip editedfile
1128 1128 This is the first line
1129 1129 This change will be committed
1130 1130 This is the third line
1131 1131 $ hg revert editedfile
1132 1132
1133 1133 Invalid patch
1134 1134
1135 1135 $ sed -e '3s/third/second/' -e '2s/will/will not/' -e 1d editedfile > tmp
1136 1136 $ mv tmp editedfile
1137 1137 $ echo "This line has been added" >> editedfile
1138 1138 $ cat > editor.sh << '__EOF__'
1139 1139 > sed s/This/That/ "$1" > tmp
1140 1140 > mv tmp "$1"
1141 1141 > __EOF__
1142 1142 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record <<EOF
1143 1143 > y
1144 1144 > e
1145 1145 > EOF
1146 1146 diff --git a/editedfile b/editedfile
1147 1147 1 hunks, 3 lines changed
1148 1148 examine changes to 'editedfile'? [Ynesfdaq?]
1149 1149 @@ -1,3 +1,3 @@
1150 1150 -This is the first line
1151 1151 -This change will be committed
1152 1152 -This is the third line
1153 1153 +This change will not be committed
1154 1154 +This is the second line
1155 1155 +This line has been added
1156 1156 record this change to 'editedfile'? [Ynesfdaq?]
1157 1157 patching file editedfile
1158 1158 Hunk #1 FAILED at 0
1159 1159 1 out of 1 hunks FAILED -- saving rejects to file editedfile.rej
1160 1160 abort: patch failed to apply
1161 1161 [255]
1162 1162 $ cat editedfile
1163 1163 This change will not be committed
1164 1164 This is the second line
1165 1165 This line has been added
1166 1166 $ hg cat -r tip editedfile
1167 1167 This is the first line
1168 1168 This change will be committed
1169 1169 This is the third line
1170 1170 $ cat editedfile.rej
1171 1171 --- editedfile
1172 1172 +++ editedfile
1173 1173 @@ -1,3 +1,3 @@
1174 1174 -That is the first line
1175 1175 -That change will be committed
1176 1176 -That is the third line
1177 1177 +That change will not be committed
1178 1178 +That is the second line
1179 1179 +That line has been added
1180 1180
1181 1181 Malformed patch - error handling
1182 1182
1183 1183 $ cat > editor.sh << '__EOF__'
1184 1184 > sed -e '/^@/p' "$1" > tmp
1185 1185 > mv tmp "$1"
1186 1186 > __EOF__
1187 1187 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record <<EOF
1188 1188 > y
1189 1189 > e
1190 1190 > EOF
1191 1191 diff --git a/editedfile b/editedfile
1192 1192 1 hunks, 3 lines changed
1193 1193 examine changes to 'editedfile'? [Ynesfdaq?]
1194 1194 @@ -1,3 +1,3 @@
1195 1195 -This is the first line
1196 1196 -This change will be committed
1197 1197 -This is the third line
1198 1198 +This change will not be committed
1199 1199 +This is the second line
1200 1200 +This line has been added
1201 1201 record this change to 'editedfile'? [Ynesfdaq?]
1202 1202 abort: error parsing patch: unhandled transition: range -> range
1203 1203 [255]
1204 1204
1205 1205 random text in random positions is still an error
1206 1206
1207 1207 $ cat > editor.sh << '__EOF__'
1208 1208 > sed -e '/^@/i\
1209 1209 > other' "$1" > tmp
1210 1210 > mv tmp "$1"
1211 1211 > __EOF__
1212 1212 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record <<EOF
1213 1213 > y
1214 1214 > e
1215 1215 > EOF
1216 1216 diff --git a/editedfile b/editedfile
1217 1217 1 hunks, 3 lines changed
1218 1218 examine changes to 'editedfile'? [Ynesfdaq?]
1219 1219 @@ -1,3 +1,3 @@
1220 1220 -This is the first line
1221 1221 -This change will be committed
1222 1222 -This is the third line
1223 1223 +This change will not be committed
1224 1224 +This is the second line
1225 1225 +This line has been added
1226 1226 record this change to 'editedfile'? [Ynesfdaq?]
1227 1227 abort: error parsing patch: unhandled transition: file -> other
1228 1228 [255]
1229 1229
1230 1230 $ hg up -C
1231 1231 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1232 1232
1233 1233 With win32text
1234 1234
1235 1235 $ echo '[extensions]' >> .hg/hgrc
1236 1236 $ echo 'win32text = ' >> .hg/hgrc
1237 1237 $ echo '[decode]' >> .hg/hgrc
1238 1238 $ echo '** = cleverdecode:' >> .hg/hgrc
1239 1239 $ echo '[encode]' >> .hg/hgrc
1240 1240 $ echo '** = cleverencode:' >> .hg/hgrc
1241 1241 $ echo '[patch]' >> .hg/hgrc
1242 1242 $ echo 'eol = crlf' >> .hg/hgrc
1243 1243
1244 1244 Ignore win32text deprecation warning for now:
1245 1245
1246 1246 $ echo '[win32text]' >> .hg/hgrc
1247 1247 $ echo 'warn = no' >> .hg/hgrc
1248 1248
1249 1249 $ echo d >> subdir/f1
1250 1250 $ hg record -d '24 0' -mw1 <<EOF
1251 1251 > y
1252 1252 > y
1253 1253 > EOF
1254 1254 diff --git a/subdir/f1 b/subdir/f1
1255 1255 1 hunks, 1 lines changed
1256 1256 examine changes to 'subdir/f1'? [Ynesfdaq?]
1257 1257 @@ -3,3 +3,4 @@
1258 1258 a
1259 1259 b
1260 1260 c
1261 1261 +d
1262 1262 record this change to 'subdir/f1'? [Ynesfdaq?]
1263 1263
1264 1264 $ hg tip -p
1265 1265 changeset: 28:* (glob)
1266 1266 tag: tip
1267 1267 user: test
1268 1268 date: Thu Jan 01 00:00:24 1970 +0000
1269 1269 summary: w1
1270 1270
1271 1271 diff -r ???????????? -r ???????????? subdir/f1 (glob)
1272 1272 --- a/subdir/f1 Thu Jan 01 00:00:23 1970 +0000
1273 1273 +++ b/subdir/f1 Thu Jan 01 00:00:24 1970 +0000
1274 1274 @@ -3,3 +3,4 @@
1275 1275 a
1276 1276 b
1277 1277 c
1278 1278 +d
1279 1279
1280 1280 Test --user when ui.username not set
1281 1281 $ unset HGUSER
1282 1282 $ echo e >> subdir/f1
1283 1283 $ hg record --config ui.username= -d '8 0' --user xyz -m "user flag" <<EOF
1284 1284 > y
1285 1285 > y
1286 1286 > EOF
1287 1287 diff --git a/subdir/f1 b/subdir/f1
1288 1288 1 hunks, 1 lines changed
1289 1289 examine changes to 'subdir/f1'? [Ynesfdaq?]
1290 1290 @@ -4,3 +4,4 @@
1291 1291 b
1292 1292 c
1293 1293 d
1294 1294 +e
1295 1295 record this change to 'subdir/f1'? [Ynesfdaq?]
1296 1296 $ hg log --template '{author}\n' -l 1
1297 1297 xyz
1298 1298 $ HGUSER="test"
1299 1299 $ export HGUSER
1300 1300
1301 1301 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now