##// END OF EJS Templates
histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler -
r18934:93f3a06b default
parent child Browse files
Show More
@@ -1,816 +1,816 b''
1 1 # histedit.py - interactive history editing for mercurial
2 2 #
3 3 # Copyright 2009 Augie Fackler <raf@durin42.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 """interactive history editing
8 8
9 9 With this extension installed, Mercurial gains one new command: histedit. Usage
10 10 is as follows, assuming the following history::
11 11
12 12 @ 3[tip] 7c2fd3b9020c 2009-04-27 18:04 -0500 durin42
13 13 | Add delta
14 14 |
15 15 o 2 030b686bedc4 2009-04-27 18:04 -0500 durin42
16 16 | Add gamma
17 17 |
18 18 o 1 c561b4e977df 2009-04-27 18:04 -0500 durin42
19 19 | Add beta
20 20 |
21 21 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
22 22 Add alpha
23 23
24 24 If you were to run ``hg histedit c561b4e977df``, you would see the following
25 25 file open in your editor::
26 26
27 27 pick c561b4e977df Add beta
28 28 pick 030b686bedc4 Add gamma
29 29 pick 7c2fd3b9020c Add delta
30 30
31 31 # Edit history between c561b4e977df and 7c2fd3b9020c
32 32 #
33 33 # Commands:
34 34 # p, pick = use commit
35 35 # e, edit = use commit, but stop for amending
36 36 # f, fold = use commit, but fold into previous commit (combines N and N-1)
37 37 # d, drop = remove commit from history
38 38 # m, mess = edit message without changing commit content
39 39 #
40 40
41 41 In this file, lines beginning with ``#`` are ignored. You must specify a rule
42 42 for each revision in your history. For example, if you had meant to add gamma
43 43 before beta, and then wanted to add delta in the same revision as beta, you
44 44 would reorganize the file to look like this::
45 45
46 46 pick 030b686bedc4 Add gamma
47 47 pick c561b4e977df Add beta
48 48 fold 7c2fd3b9020c Add delta
49 49
50 50 # Edit history between c561b4e977df and 7c2fd3b9020c
51 51 #
52 52 # Commands:
53 53 # p, pick = use commit
54 54 # e, edit = use commit, but stop for amending
55 55 # f, fold = use commit, but fold into previous commit (combines N and N-1)
56 56 # d, drop = remove commit from history
57 57 # m, mess = edit message without changing commit content
58 58 #
59 59
60 60 At which point you close the editor and ``histedit`` starts working. When you
61 61 specify a ``fold`` operation, ``histedit`` will open an editor when it folds
62 62 those revisions together, offering you a chance to clean up the commit message::
63 63
64 64 Add beta
65 65 ***
66 66 Add delta
67 67
68 68 Edit the commit message to your liking, then close the editor. For
69 69 this example, let's assume that the commit message was changed to
70 70 ``Add beta and delta.`` After histedit has run and had a chance to
71 71 remove any old or temporary revisions it needed, the history looks
72 72 like this::
73 73
74 74 @ 2[tip] 989b4d060121 2009-04-27 18:04 -0500 durin42
75 75 | Add beta and delta.
76 76 |
77 77 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
78 78 | Add gamma
79 79 |
80 80 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
81 81 Add alpha
82 82
83 83 Note that ``histedit`` does *not* remove any revisions (even its own temporary
84 84 ones) until after it has completed all the editing operations, so it will
85 85 probably perform several strip operations when it's done. For the above example,
86 86 it had to run strip twice. Strip can be slow depending on a variety of factors,
87 87 so you might need to be a little patient. You can choose to keep the original
88 88 revisions by passing the ``--keep`` flag.
89 89
90 90 The ``edit`` operation will drop you back to a command prompt,
91 91 allowing you to edit files freely, or even use ``hg record`` to commit
92 92 some changes as a separate commit. When you're done, any remaining
93 93 uncommitted changes will be committed as well. When done, run ``hg
94 94 histedit --continue`` to finish this step. You'll be prompted for a
95 95 new commit message, but the default commit message will be the
96 96 original message for the ``edit`` ed revision.
97 97
98 98 The ``message`` operation will give you a chance to revise a commit
99 99 message without changing the contents. It's a shortcut for doing
100 100 ``edit`` immediately followed by `hg histedit --continue``.
101 101
102 102 If ``histedit`` encounters a conflict when moving a revision (while
103 103 handling ``pick`` or ``fold``), it'll stop in a similar manner to
104 104 ``edit`` with the difference that it won't prompt you for a commit
105 105 message when done. If you decide at this point that you don't like how
106 106 much work it will be to rearrange history, or that you made a mistake,
107 107 you can use ``hg histedit --abort`` to abandon the new changes you
108 108 have made and return to the state before you attempted to edit your
109 109 history.
110 110
111 111 If we clone the histedit-ed example repository above and add four more
112 112 changes, such that we have the following history::
113 113
114 114 @ 6[tip] 038383181893 2009-04-27 18:04 -0500 stefan
115 115 | Add theta
116 116 |
117 117 o 5 140988835471 2009-04-27 18:04 -0500 stefan
118 118 | Add eta
119 119 |
120 120 o 4 122930637314 2009-04-27 18:04 -0500 stefan
121 121 | Add zeta
122 122 |
123 123 o 3 836302820282 2009-04-27 18:04 -0500 stefan
124 124 | Add epsilon
125 125 |
126 126 o 2 989b4d060121 2009-04-27 18:04 -0500 durin42
127 127 | Add beta and delta.
128 128 |
129 129 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
130 130 | Add gamma
131 131 |
132 132 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
133 133 Add alpha
134 134
135 135 If you run ``hg histedit --outgoing`` on the clone then it is the same
136 136 as running ``hg histedit 836302820282``. If you need plan to push to a
137 137 repository that Mercurial does not detect to be related to the source
138 138 repo, you can add a ``--force`` option.
139 139 """
140 140
141 141 try:
142 142 import cPickle as pickle
143 143 except ImportError:
144 144 import pickle
145 145 import os
146 146
147 147 from mercurial import cmdutil
148 148 from mercurial import discovery
149 149 from mercurial import error
150 150 from mercurial import copies
151 151 from mercurial import context
152 152 from mercurial import hg
153 153 from mercurial import lock as lockmod
154 154 from mercurial import node
155 155 from mercurial import repair
156 156 from mercurial import scmutil
157 157 from mercurial import util
158 158 from mercurial import obsolete
159 159 from mercurial import merge as mergemod
160 160 from mercurial.i18n import _
161 161
162 162 cmdtable = {}
163 163 command = cmdutil.command(cmdtable)
164 164
165 165 testedwith = 'internal'
166 166
167 167 # i18n: command names and abbreviations must remain untranslated
168 168 editcomment = _("""# Edit history between %s and %s
169 169 #
170 170 # Commands:
171 171 # p, pick = use commit
172 172 # e, edit = use commit, but stop for amending
173 173 # f, fold = use commit, but fold into previous commit (combines N and N-1)
174 174 # d, drop = remove commit from history
175 175 # m, mess = edit message without changing commit content
176 176 #
177 177 """)
178 178
179 179 def commitfuncfor(repo, src):
180 180 """Build a commit function for the replacement of <src>
181 181
182 182 This function ensure we apply the same treatment to all changesets.
183 183
184 184 - Add a 'histedit_source' entry in extra.
185 185
186 186 Note that fold have its own separated logic because its handling is a bit
187 187 different and not easily factored out of the fold method.
188 188 """
189 189 phasemin = src.phase()
190 190 def commitfunc(**kwargs):
191 191 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
192 192 try:
193 193 repo.ui.setconfig('phases', 'new-commit', phasemin)
194 194 extra = kwargs.get('extra', {}).copy()
195 195 extra['histedit_source'] = src.hex()
196 196 kwargs['extra'] = extra
197 197 return repo.commit(**kwargs)
198 198 finally:
199 199 repo.ui.restoreconfig(phasebackup)
200 200 return commitfunc
201 201
202 202
203 203
204 204 def applychanges(ui, repo, ctx, opts):
205 205 """Merge changeset from ctx (only) in the current working directory"""
206 206 wcpar = repo.dirstate.parents()[0]
207 207 if ctx.p1().node() == wcpar:
208 208 # edition ar "in place" we do not need to make any merge,
209 209 # just applies changes on parent for edition
210 210 cmdutil.revert(ui, repo, ctx, (wcpar, node.nullid), all=True)
211 211 stats = None
212 212 else:
213 213 try:
214 214 # ui.forcemerge is an internal variable, do not document
215 215 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
216 216 stats = mergemod.update(repo, ctx.node(), True, True, False,
217 217 ctx.p1().node())
218 218 finally:
219 219 repo.ui.setconfig('ui', 'forcemerge', '')
220 220 repo.setparents(wcpar, node.nullid)
221 221 repo.dirstate.write()
222 222 # fix up dirstate for copies and renames
223 223 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
224 224 return stats
225 225
226 226 def collapse(repo, first, last, commitopts):
227 227 """collapse the set of revisions from first to last as new one.
228 228
229 229 Expected commit options are:
230 230 - message
231 231 - date
232 232 - username
233 233 Commit message is edited in all cases.
234 234
235 235 This function works in memory."""
236 236 ctxs = list(repo.set('%d::%d', first, last))
237 237 if not ctxs:
238 238 return None
239 239 base = first.parents()[0]
240 240
241 241 # commit a new version of the old changeset, including the update
242 242 # collect all files which might be affected
243 243 files = set()
244 244 for ctx in ctxs:
245 245 files.update(ctx.files())
246 246
247 247 # Recompute copies (avoid recording a -> b -> a)
248 248 copied = copies.pathcopies(first, last)
249 249
250 250 # prune files which were reverted by the updates
251 251 def samefile(f):
252 252 if f in last.manifest():
253 253 a = last.filectx(f)
254 254 if f in base.manifest():
255 255 b = base.filectx(f)
256 256 return (a.data() == b.data()
257 257 and a.flags() == b.flags())
258 258 else:
259 259 return False
260 260 else:
261 261 return f not in base.manifest()
262 262 files = [f for f in files if not samefile(f)]
263 263 # commit version of these files as defined by head
264 264 headmf = last.manifest()
265 265 def filectxfn(repo, ctx, path):
266 266 if path in headmf:
267 267 fctx = last[path]
268 268 flags = fctx.flags()
269 269 mctx = context.memfilectx(fctx.path(), fctx.data(),
270 270 islink='l' in flags,
271 271 isexec='x' in flags,
272 272 copied=copied.get(path))
273 273 return mctx
274 274 raise IOError()
275 275
276 276 if commitopts.get('message'):
277 277 message = commitopts['message']
278 278 else:
279 279 message = first.description()
280 280 user = commitopts.get('user')
281 281 date = commitopts.get('date')
282 282 extra = commitopts.get('extra')
283 283
284 284 parents = (first.p1().node(), first.p2().node())
285 285 new = context.memctx(repo,
286 286 parents=parents,
287 287 text=message,
288 288 files=files,
289 289 filectxfn=filectxfn,
290 290 user=user,
291 291 date=date,
292 292 extra=extra)
293 293 new._text = cmdutil.commitforceeditor(repo, new, [])
294 294 return repo.commitctx(new)
295 295
296 296 def pick(ui, repo, ctx, ha, opts):
297 297 oldctx = repo[ha]
298 298 if oldctx.parents()[0] == ctx:
299 299 ui.debug('node %s unchanged\n' % ha)
300 300 return oldctx, []
301 301 hg.update(repo, ctx.node())
302 302 stats = applychanges(ui, repo, oldctx, opts)
303 303 if stats and stats[3] > 0:
304 raise util.Abort(_('Fix up the change and run '
305 'hg histedit --continue'))
304 raise error.InterventionRequired(_('Fix up the change and run '
305 'hg histedit --continue'))
306 306 # drop the second merge parent
307 307 commit = commitfuncfor(repo, oldctx)
308 308 n = commit(text=oldctx.description(), user=oldctx.user(),
309 309 date=oldctx.date(), extra=oldctx.extra())
310 310 if n is None:
311 311 ui.warn(_('%s: empty changeset\n')
312 312 % node.hex(ha))
313 313 return ctx, []
314 314 new = repo[n]
315 315 return new, [(oldctx.node(), (n,))]
316 316
317 317
318 318 def edit(ui, repo, ctx, ha, opts):
319 319 oldctx = repo[ha]
320 320 hg.update(repo, ctx.node())
321 321 applychanges(ui, repo, oldctx, opts)
322 raise util.Abort(_('Make changes as needed, you may commit or record as '
323 'needed now.\nWhen you are finished, run hg'
324 ' histedit --continue to resume.'))
322 raise error.InterventionRequired(
323 _('Make changes as needed, you may commit or record as needed now.\n'
324 'When you are finished, run hg histedit --continue to resume.'))
325 325
326 326 def fold(ui, repo, ctx, ha, opts):
327 327 oldctx = repo[ha]
328 328 hg.update(repo, ctx.node())
329 329 stats = applychanges(ui, repo, oldctx, opts)
330 330 if stats and stats[3] > 0:
331 raise util.Abort(_('Fix up the change and run '
332 'hg histedit --continue'))
331 raise error.InterventionRequired(
332 _('Fix up the change and run hg histedit --continue'))
333 333 n = repo.commit(text='fold-temp-revision %s' % ha, user=oldctx.user(),
334 334 date=oldctx.date(), extra=oldctx.extra())
335 335 if n is None:
336 336 ui.warn(_('%s: empty changeset')
337 337 % node.hex(ha))
338 338 return ctx, []
339 339 return finishfold(ui, repo, ctx, oldctx, n, opts, [])
340 340
341 341 def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges):
342 342 parent = ctx.parents()[0].node()
343 343 hg.update(repo, parent)
344 344 ### prepare new commit data
345 345 commitopts = opts.copy()
346 346 # username
347 347 if ctx.user() == oldctx.user():
348 348 username = ctx.user()
349 349 else:
350 350 username = ui.username()
351 351 commitopts['user'] = username
352 352 # commit message
353 353 newmessage = '\n***\n'.join(
354 354 [ctx.description()] +
355 355 [repo[r].description() for r in internalchanges] +
356 356 [oldctx.description()]) + '\n'
357 357 commitopts['message'] = newmessage
358 358 # date
359 359 commitopts['date'] = max(ctx.date(), oldctx.date())
360 360 extra = ctx.extra().copy()
361 361 # histedit_source
362 362 # note: ctx is likely a temporary commit but that the best we can do here
363 363 # This is sufficient to solve issue3681 anyway
364 364 extra['histedit_source'] = '%s,%s' % (ctx.hex(), oldctx.hex())
365 365 commitopts['extra'] = extra
366 366 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
367 367 try:
368 368 phasemin = max(ctx.phase(), oldctx.phase())
369 369 repo.ui.setconfig('phases', 'new-commit', phasemin)
370 370 n = collapse(repo, ctx, repo[newnode], commitopts)
371 371 finally:
372 372 repo.ui.restoreconfig(phasebackup)
373 373 if n is None:
374 374 return ctx, []
375 375 hg.update(repo, n)
376 376 replacements = [(oldctx.node(), (newnode,)),
377 377 (ctx.node(), (n,)),
378 378 (newnode, (n,)),
379 379 ]
380 380 for ich in internalchanges:
381 381 replacements.append((ich, (n,)))
382 382 return repo[n], replacements
383 383
384 384 def drop(ui, repo, ctx, ha, opts):
385 385 return ctx, [(repo[ha].node(), ())]
386 386
387 387
388 388 def message(ui, repo, ctx, ha, opts):
389 389 oldctx = repo[ha]
390 390 hg.update(repo, ctx.node())
391 391 stats = applychanges(ui, repo, oldctx, opts)
392 392 if stats and stats[3] > 0:
393 raise util.Abort(_('Fix up the change and run '
394 'hg histedit --continue'))
393 raise error.InterventionRequired(
394 _('Fix up the change and run hg histedit --continue'))
395 395 message = oldctx.description() + '\n'
396 396 message = ui.edit(message, ui.username())
397 397 commit = commitfuncfor(repo, oldctx)
398 398 new = commit(text=message, user=oldctx.user(), date=oldctx.date(),
399 399 extra=oldctx.extra())
400 400 newctx = repo[new]
401 401 if oldctx.node() != newctx.node():
402 402 return newctx, [(oldctx.node(), (new,))]
403 403 # We didn't make an edit, so just indicate no replaced nodes
404 404 return newctx, []
405 405
406 406 actiontable = {'p': pick,
407 407 'pick': pick,
408 408 'e': edit,
409 409 'edit': edit,
410 410 'f': fold,
411 411 'fold': fold,
412 412 'd': drop,
413 413 'drop': drop,
414 414 'm': message,
415 415 'mess': message,
416 416 }
417 417
418 418 @command('histedit',
419 419 [('', 'commands', '',
420 420 _('Read history edits from the specified file.')),
421 421 ('c', 'continue', False, _('continue an edit already in progress')),
422 422 ('k', 'keep', False,
423 423 _("don't strip old nodes after edit is complete")),
424 424 ('', 'abort', False, _('abort an edit in progress')),
425 425 ('o', 'outgoing', False, _('changesets not found in destination')),
426 426 ('f', 'force', False,
427 427 _('force outgoing even for unrelated repositories')),
428 428 ('r', 'rev', [], _('first revision to be edited'))],
429 429 _("[PARENT]"))
430 430 def histedit(ui, repo, *parent, **opts):
431 431 """interactively edit changeset history
432 432 """
433 433 # TODO only abort if we try and histedit mq patches, not just
434 434 # blanket if mq patches are applied somewhere
435 435 mq = getattr(repo, 'mq', None)
436 436 if mq and mq.applied:
437 437 raise util.Abort(_('source has mq patches applied'))
438 438
439 439 parent = list(parent) + opts.get('rev', [])
440 440 if opts.get('outgoing'):
441 441 if len(parent) > 1:
442 442 raise util.Abort(
443 443 _('only one repo argument allowed with --outgoing'))
444 444 elif parent:
445 445 parent = parent[0]
446 446
447 447 dest = ui.expandpath(parent or 'default-push', parent or 'default')
448 448 dest, revs = hg.parseurl(dest, None)[:2]
449 449 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
450 450
451 451 revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
452 452 other = hg.peer(repo, opts, dest)
453 453
454 454 if revs:
455 455 revs = [repo.lookup(rev) for rev in revs]
456 456
457 457 # hexlify nodes from outgoing, because we're going to parse
458 458 # parent[0] using revsingle below, and if the binary hash
459 459 # contains special revset characters like ":" the revset
460 460 # parser can choke.
461 461 parent = [node.hex(n) for n in discovery.findcommonoutgoing(
462 462 repo, other, [], force=opts.get('force')).missing[0:1]]
463 463 else:
464 464 if opts.get('force'):
465 465 raise util.Abort(_('--force only allowed with --outgoing'))
466 466
467 467 if opts.get('continue', False):
468 468 if len(parent) != 0:
469 469 raise util.Abort(_('no arguments allowed with --continue'))
470 470 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
471 471 currentparent, wantnull = repo.dirstate.parents()
472 472 parentctx = repo[parentctxnode]
473 473 parentctx, repl = bootstrapcontinue(ui, repo, parentctx, rules, opts)
474 474 replacements.extend(repl)
475 475 elif opts.get('abort', False):
476 476 if len(parent) != 0:
477 477 raise util.Abort(_('no arguments allowed with --abort'))
478 478 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
479 479 mapping, tmpnodes, leafs, _ntm = processreplacement(repo, replacements)
480 480 ui.debug('restore wc to old parent %s\n' % node.short(topmost))
481 481 hg.clean(repo, topmost)
482 482 cleanupnode(ui, repo, 'created', tmpnodes)
483 483 cleanupnode(ui, repo, 'temp', leafs)
484 484 os.unlink(os.path.join(repo.path, 'histedit-state'))
485 485 return
486 486 else:
487 487 cmdutil.bailifchanged(repo)
488 488 if os.path.exists(os.path.join(repo.path, 'histedit-state')):
489 489 raise util.Abort(_('history edit already in progress, try '
490 490 '--continue or --abort'))
491 491
492 492 topmost, empty = repo.dirstate.parents()
493 493
494 494 if len(parent) != 1:
495 495 raise util.Abort(_('histedit requires exactly one parent revision'))
496 496 parent = scmutil.revsingle(repo, parent[0]).node()
497 497
498 498 keep = opts.get('keep', False)
499 499 revs = between(repo, parent, topmost, keep)
500 500 if not revs:
501 501 raise util.Abort(_('%s is not an ancestor of working directory') %
502 502 node.short(parent))
503 503
504 504 ctxs = [repo[r] for r in revs]
505 505 rules = opts.get('commands', '')
506 506 if not rules:
507 507 rules = '\n'.join([makedesc(c) for c in ctxs])
508 508 rules += '\n\n'
509 509 rules += editcomment % (node.short(parent), node.short(topmost))
510 510 rules = ui.edit(rules, ui.username())
511 511 # Save edit rules in .hg/histedit-last-edit.txt in case
512 512 # the user needs to ask for help after something
513 513 # surprising happens.
514 514 f = open(repo.join('histedit-last-edit.txt'), 'w')
515 515 f.write(rules)
516 516 f.close()
517 517 else:
518 518 f = open(rules)
519 519 rules = f.read()
520 520 f.close()
521 521 rules = [l for l in (r.strip() for r in rules.splitlines())
522 522 if l and not l[0] == '#']
523 523 rules = verifyrules(rules, repo, ctxs)
524 524
525 525 parentctx = repo[parent].parents()[0]
526 526 keep = opts.get('keep', False)
527 527 replacements = []
528 528
529 529
530 530 while rules:
531 531 writestate(repo, parentctx.node(), rules, keep, topmost, replacements)
532 532 action, ha = rules.pop(0)
533 533 ui.debug('histedit: processing %s %s\n' % (action, ha))
534 534 actfunc = actiontable[action]
535 535 parentctx, replacement_ = actfunc(ui, repo, parentctx, ha, opts)
536 536 replacements.extend(replacement_)
537 537
538 538 hg.update(repo, parentctx.node())
539 539
540 540 mapping, tmpnodes, created, ntm = processreplacement(repo, replacements)
541 541 if mapping:
542 542 for prec, succs in mapping.iteritems():
543 543 if not succs:
544 544 ui.debug('histedit: %s is dropped\n' % node.short(prec))
545 545 else:
546 546 ui.debug('histedit: %s is replaced by %s\n' % (
547 547 node.short(prec), node.short(succs[0])))
548 548 if len(succs) > 1:
549 549 m = 'histedit: %s'
550 550 for n in succs[1:]:
551 551 ui.debug(m % node.short(n))
552 552
553 553 if not keep:
554 554 if mapping:
555 555 movebookmarks(ui, repo, mapping, topmost, ntm)
556 556 # TODO update mq state
557 557 if obsolete._enabled:
558 558 markers = []
559 559 # sort by revision number because it sound "right"
560 560 for prec in sorted(mapping, key=repo.changelog.rev):
561 561 succs = mapping[prec]
562 562 markers.append((repo[prec],
563 563 tuple(repo[s] for s in succs)))
564 564 if markers:
565 565 obsolete.createmarkers(repo, markers)
566 566 else:
567 567 cleanupnode(ui, repo, 'replaced', mapping)
568 568
569 569 cleanupnode(ui, repo, 'temp', tmpnodes)
570 570 os.unlink(os.path.join(repo.path, 'histedit-state'))
571 571 if os.path.exists(repo.sjoin('undo')):
572 572 os.unlink(repo.sjoin('undo'))
573 573
574 574
575 575 def bootstrapcontinue(ui, repo, parentctx, rules, opts):
576 576 action, currentnode = rules.pop(0)
577 577 ctx = repo[currentnode]
578 578 # is there any new commit between the expected parent and "."
579 579 #
580 580 # note: does not take non linear new change in account (but previous
581 581 # implementation didn't used them anyway (issue3655)
582 582 newchildren = [c.node() for c in repo.set('(%d::.)', parentctx)]
583 583 if parentctx.node() != node.nullid:
584 584 if not newchildren:
585 585 # `parentctxnode` should match but no result. This means that
586 586 # currentnode is not a descendant from parentctxnode.
587 587 msg = _('%s is not an ancestor of working directory')
588 588 hint = _('update to %s or descendant and run "hg histedit '
589 589 '--continue" again') % parentctx
590 590 raise util.Abort(msg % parentctx, hint=hint)
591 591 newchildren.pop(0) # remove parentctxnode
592 592 # Commit dirty working directory if necessary
593 593 new = None
594 594 m, a, r, d = repo.status()[:4]
595 595 if m or a or r or d:
596 596 # prepare the message for the commit to comes
597 597 if action in ('f', 'fold'):
598 598 message = 'fold-temp-revision %s' % currentnode
599 599 else:
600 600 message = ctx.description() + '\n'
601 601 if action in ('e', 'edit', 'm', 'mess'):
602 602 editor = cmdutil.commitforceeditor
603 603 else:
604 604 editor = False
605 605 commit = commitfuncfor(repo, ctx)
606 606 new = commit(text=message, user=ctx.user(),
607 607 date=ctx.date(), extra=ctx.extra(),
608 608 editor=editor)
609 609 if new is not None:
610 610 newchildren.append(new)
611 611
612 612 replacements = []
613 613 # track replacements
614 614 if ctx.node() not in newchildren:
615 615 # note: new children may be empty when the changeset is dropped.
616 616 # this happen e.g during conflicting pick where we revert content
617 617 # to parent.
618 618 replacements.append((ctx.node(), tuple(newchildren)))
619 619
620 620 if action in ('f', 'fold'):
621 621 # finalize fold operation if applicable
622 622 if new is None:
623 623 new = newchildren[-1]
624 624 else:
625 625 newchildren.pop() # remove new from internal changes
626 626 parentctx, repl = finishfold(ui, repo, parentctx, ctx, new, opts,
627 627 newchildren)
628 628 replacements.extend(repl)
629 629 elif newchildren:
630 630 # otherwise update "parentctx" before proceeding to further operation
631 631 parentctx = repo[newchildren[-1]]
632 632 return parentctx, replacements
633 633
634 634
635 635 def between(repo, old, new, keep):
636 636 """select and validate the set of revision to edit
637 637
638 638 When keep is false, the specified set can't have children."""
639 639 ctxs = list(repo.set('%n::%n', old, new))
640 640 if ctxs and not keep:
641 641 if (not obsolete._enabled and
642 642 repo.revs('(%ld::) - (%ld)', ctxs, ctxs)):
643 643 raise util.Abort(_('cannot edit history that would orphan nodes'))
644 644 root = ctxs[0] # list is already sorted by repo.set
645 645 if not root.phase():
646 646 raise util.Abort(_('cannot edit immutable changeset: %s') % root)
647 647 return [c.node() for c in ctxs]
648 648
649 649
650 650 def writestate(repo, parentnode, rules, keep, topmost, replacements):
651 651 fp = open(os.path.join(repo.path, 'histedit-state'), 'w')
652 652 pickle.dump((parentnode, rules, keep, topmost, replacements), fp)
653 653 fp.close()
654 654
655 655 def readstate(repo):
656 656 """Returns a tuple of (parentnode, rules, keep, topmost, replacements).
657 657 """
658 658 fp = open(os.path.join(repo.path, 'histedit-state'))
659 659 return pickle.load(fp)
660 660
661 661
662 662 def makedesc(c):
663 663 """build a initial action line for a ctx `c`
664 664
665 665 line are in the form:
666 666
667 667 pick <hash> <rev> <summary>
668 668 """
669 669 summary = ''
670 670 if c.description():
671 671 summary = c.description().splitlines()[0]
672 672 line = 'pick %s %d %s' % (c, c.rev(), summary)
673 673 return line[:80] # trim to 80 chars so it's not stupidly wide in my editor
674 674
675 675 def verifyrules(rules, repo, ctxs):
676 676 """Verify that there exists exactly one edit rule per given changeset.
677 677
678 678 Will abort if there are to many or too few rules, a malformed rule,
679 679 or a rule on a changeset outside of the user-given range.
680 680 """
681 681 parsed = []
682 682 if len(rules) != len(ctxs):
683 683 raise util.Abort(_('must specify a rule for each changeset once'))
684 684 for r in rules:
685 685 if ' ' not in r:
686 686 raise util.Abort(_('malformed line "%s"') % r)
687 687 action, rest = r.split(' ', 1)
688 688 if ' ' in rest.strip():
689 689 ha, rest = rest.split(' ', 1)
690 690 else:
691 691 ha = r.strip()
692 692 try:
693 693 if repo[ha] not in ctxs:
694 694 raise util.Abort(
695 695 _('may not use changesets other than the ones listed'))
696 696 except error.RepoError:
697 697 raise util.Abort(_('unknown changeset %s listed') % ha)
698 698 if action not in actiontable:
699 699 raise util.Abort(_('unknown action "%s"') % action)
700 700 parsed.append([action, ha])
701 701 return parsed
702 702
703 703 def processreplacement(repo, replacements):
704 704 """process the list of replacements to return
705 705
706 706 1) the final mapping between original and created nodes
707 707 2) the list of temporary node created by histedit
708 708 3) the list of new commit created by histedit"""
709 709 allsuccs = set()
710 710 replaced = set()
711 711 fullmapping = {}
712 712 # initialise basic set
713 713 # fullmapping record all operation recorded in replacement
714 714 for rep in replacements:
715 715 allsuccs.update(rep[1])
716 716 replaced.add(rep[0])
717 717 fullmapping.setdefault(rep[0], set()).update(rep[1])
718 718 new = allsuccs - replaced
719 719 tmpnodes = allsuccs & replaced
720 720 # Reduce content fullmapping into direct relation between original nodes
721 721 # and final node created during history edition
722 722 # Dropped changeset are replaced by an empty list
723 723 toproceed = set(fullmapping)
724 724 final = {}
725 725 while toproceed:
726 726 for x in list(toproceed):
727 727 succs = fullmapping[x]
728 728 for s in list(succs):
729 729 if s in toproceed:
730 730 # non final node with unknown closure
731 731 # We can't process this now
732 732 break
733 733 elif s in final:
734 734 # non final node, replace with closure
735 735 succs.remove(s)
736 736 succs.update(final[s])
737 737 else:
738 738 final[x] = succs
739 739 toproceed.remove(x)
740 740 # remove tmpnodes from final mapping
741 741 for n in tmpnodes:
742 742 del final[n]
743 743 # we expect all changes involved in final to exist in the repo
744 744 # turn `final` into list (topologically sorted)
745 745 nm = repo.changelog.nodemap
746 746 for prec, succs in final.items():
747 747 final[prec] = sorted(succs, key=nm.get)
748 748
749 749 # computed topmost element (necessary for bookmark)
750 750 if new:
751 751 newtopmost = sorted(new, key=repo.changelog.rev)[-1]
752 752 elif not final:
753 753 # Nothing rewritten at all. we won't need `newtopmost`
754 754 # It is the same as `oldtopmost` and `processreplacement` know it
755 755 newtopmost = None
756 756 else:
757 757 # every body died. The newtopmost is the parent of the root.
758 758 newtopmost = repo[sorted(final, key=repo.changelog.rev)[0]].p1().node()
759 759
760 760 return final, tmpnodes, new, newtopmost
761 761
762 762 def movebookmarks(ui, repo, mapping, oldtopmost, newtopmost):
763 763 """Move bookmark from old to newly created node"""
764 764 if not mapping:
765 765 # if nothing got rewritten there is not purpose for this function
766 766 return
767 767 moves = []
768 768 for bk, old in sorted(repo._bookmarks.iteritems()):
769 769 if old == oldtopmost:
770 770 # special case ensure bookmark stay on tip.
771 771 #
772 772 # This is arguably a feature and we may only want that for the
773 773 # active bookmark. But the behavior is kept compatible with the old
774 774 # version for now.
775 775 moves.append((bk, newtopmost))
776 776 continue
777 777 base = old
778 778 new = mapping.get(base, None)
779 779 if new is None:
780 780 continue
781 781 while not new:
782 782 # base is killed, trying with parent
783 783 base = repo[base].p1().node()
784 784 new = mapping.get(base, (base,))
785 785 # nothing to move
786 786 moves.append((bk, new[-1]))
787 787 if moves:
788 788 marks = repo._bookmarks
789 789 for mark, new in moves:
790 790 old = marks[mark]
791 791 ui.note(_('histedit: moving bookmarks %s from %s to %s\n')
792 792 % (mark, node.short(old), node.short(new)))
793 793 marks[mark] = new
794 794 marks.write()
795 795
796 796 def cleanupnode(ui, repo, name, nodes):
797 797 """strip a group of nodes from the repository
798 798
799 799 The set of node to strip may contains unknown nodes."""
800 800 ui.debug('should strip %s nodes %s\n' %
801 801 (name, ', '.join([node.short(n) for n in nodes])))
802 802 lock = None
803 803 try:
804 804 lock = repo.lock()
805 805 # Find all node that need to be stripped
806 806 # (we hg %lr instead of %ln to silently ignore unknown item
807 807 nm = repo.changelog.nodemap
808 808 nodes = [n for n in nodes if n in nm]
809 809 roots = [c.node() for c in repo.set("roots(%ln)", nodes)]
810 810 for c in roots:
811 811 # We should process node in reverse order to strip tip most first.
812 812 # but this trigger a bug in changegroup hook.
813 813 # This would reduce bundle overhead
814 814 repair.strip(ui, repo, c)
815 815 finally:
816 816 lockmod.release(lock)
@@ -1,224 +1,224 b''
1 1 $ . "$TESTDIR/histedit-helpers.sh"
2 2
3 3 $ cat >> $HGRCPATH <<EOF
4 4 > [extensions]
5 5 > graphlog=
6 6 > histedit=
7 7 > EOF
8 8
9 9 $ EDITED="$TESTTMP/editedhistory"
10 10 $ cat > $EDITED <<EOF
11 11 > pick 177f92b77385 c
12 12 > pick 055a42cdd887 d
13 13 > edit e860deea161a e
14 14 > pick 652413bf663e f
15 15 > EOF
16 16 $ initrepo ()
17 17 > {
18 18 > hg init r
19 19 > cd r
20 20 > for x in a b c d e f ; do
21 21 > echo $x > $x
22 22 > hg add $x
23 23 > hg ci -m $x
24 24 > done
25 25 > }
26 26
27 27 $ initrepo
28 28
29 29 log before edit
30 30 $ hg log --graph
31 31 @ changeset: 5:652413bf663e
32 32 | tag: tip
33 33 | user: test
34 34 | date: Thu Jan 01 00:00:00 1970 +0000
35 35 | summary: f
36 36 |
37 37 o changeset: 4:e860deea161a
38 38 | user: test
39 39 | date: Thu Jan 01 00:00:00 1970 +0000
40 40 | summary: e
41 41 |
42 42 o changeset: 3:055a42cdd887
43 43 | user: test
44 44 | date: Thu Jan 01 00:00:00 1970 +0000
45 45 | summary: d
46 46 |
47 47 o changeset: 2:177f92b77385
48 48 | user: test
49 49 | date: Thu Jan 01 00:00:00 1970 +0000
50 50 | summary: c
51 51 |
52 52 o changeset: 1:d2ae7f538514
53 53 | user: test
54 54 | date: Thu Jan 01 00:00:00 1970 +0000
55 55 | summary: b
56 56 |
57 57 o changeset: 0:cb9a9f314b8b
58 58 user: test
59 59 date: Thu Jan 01 00:00:00 1970 +0000
60 60 summary: a
61 61
62 62
63 63 edit the history
64 64 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
65 65 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
66 abort: Make changes as needed, you may commit or record as needed now.
66 Make changes as needed, you may commit or record as needed now.
67 67 When you are finished, run hg histedit --continue to resume.
68 68
69 69 Go at a random point and try to continue
70 70
71 71 $ hg id -n
72 72 3+
73 73 $ hg up 0
74 74 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
75 75 $ HGEDITOR='echo foobaz > ' hg histedit --continue
76 76 abort: 055a42cdd887 is not an ancestor of working directory
77 77 (update to 055a42cdd887 or descendant and run "hg histedit --continue" again)
78 78 [255]
79 79 $ hg up 3
80 80 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
81 81
82 82 commit, then edit the revision
83 83 $ hg ci -m 'wat'
84 84 created new head
85 85 $ echo a > e
86 86 $ HGEDITOR='echo foobaz > ' hg histedit --continue 2>&1 | fixbundle
87 87 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 88 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 89
90 90 $ hg log --graph
91 91 @ changeset: 6:b5f70786f9b0
92 92 | tag: tip
93 93 | user: test
94 94 | date: Thu Jan 01 00:00:00 1970 +0000
95 95 | summary: f
96 96 |
97 97 o changeset: 5:a5e1ba2f7afb
98 98 | user: test
99 99 | date: Thu Jan 01 00:00:00 1970 +0000
100 100 | summary: foobaz
101 101 |
102 102 o changeset: 4:1a60820cd1f6
103 103 | user: test
104 104 | date: Thu Jan 01 00:00:00 1970 +0000
105 105 | summary: wat
106 106 |
107 107 o changeset: 3:055a42cdd887
108 108 | user: test
109 109 | date: Thu Jan 01 00:00:00 1970 +0000
110 110 | summary: d
111 111 |
112 112 o changeset: 2:177f92b77385
113 113 | user: test
114 114 | date: Thu Jan 01 00:00:00 1970 +0000
115 115 | summary: c
116 116 |
117 117 o changeset: 1:d2ae7f538514
118 118 | user: test
119 119 | date: Thu Jan 01 00:00:00 1970 +0000
120 120 | summary: b
121 121 |
122 122 o changeset: 0:cb9a9f314b8b
123 123 user: test
124 124 date: Thu Jan 01 00:00:00 1970 +0000
125 125 summary: a
126 126
127 127
128 128 $ hg cat e
129 129 a
130 130
131 131 check histedit_source
132 132
133 133 $ hg log --debug --rev 5
134 134 changeset: 5:a5e1ba2f7afb899ef1581cea528fd885d2fca70d
135 135 phase: draft
136 136 parent: 4:1a60820cd1f6004a362aa622ebc47d59bc48eb34
137 137 parent: -1:0000000000000000000000000000000000000000
138 138 manifest: 5:5ad3be8791f39117565557781f5464363b918a45
139 139 user: test
140 140 date: Thu Jan 01 00:00:00 1970 +0000
141 141 files: e
142 142 extra: branch=default
143 143 extra: histedit_source=e860deea161a2f77de56603b340ebbb4536308ae
144 144 description:
145 145 foobaz
146 146
147 147
148 148
149 149 $ cat > $EDITED <<EOF
150 150 > edit b5f70786f9b0 f
151 151 > EOF
152 152 $ HGEDITOR="cat \"$EDITED\" > " hg histedit tip 2>&1 | fixbundle
153 153 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
154 abort: Make changes as needed, you may commit or record as needed now.
154 Make changes as needed, you may commit or record as needed now.
155 155 When you are finished, run hg histedit --continue to resume.
156 156 $ hg status
157 157 A f
158 158 $ HGEDITOR='true' hg histedit --continue
159 159 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 160 saved backup bundle to $TESTTMP/r/.hg/strip-backup/b5f70786f9b0-backup.hg (glob)
161 161
162 162 $ hg status
163 163
164 164 log after edit
165 165 $ hg log --limit 1
166 166 changeset: 6:a107ee126658
167 167 tag: tip
168 168 user: test
169 169 date: Thu Jan 01 00:00:00 1970 +0000
170 170 summary: f
171 171
172 172
173 173 say we'll change the message, but don't.
174 174 $ cat > ../edit.sh <<EOF
175 175 > cat "\$1" | sed s/pick/mess/ > tmp
176 176 > mv tmp "\$1"
177 177 > EOF
178 178 $ HGEDITOR="sh ../edit.sh" hg histedit tip 2>&1 | fixbundle
179 179 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
180 180 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
181 181 $ hg status
182 182 $ hg log --limit 1
183 183 changeset: 6:1fd3b2fe7754
184 184 tag: tip
185 185 user: test
186 186 date: Thu Jan 01 00:00:00 1970 +0000
187 187 summary: f
188 188
189 189
190 190 modify the message
191 191 $ cat > $EDITED <<EOF
192 192 > mess 1fd3b2fe7754 f
193 193 > EOF
194 194 $ HGEDITOR="cat \"$EDITED\" > " hg histedit tip 2>&1 | fixbundle
195 195 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
196 196 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
197 197 $ hg status
198 198 $ hg log --limit 1
199 199 changeset: 6:5585e802ef99
200 200 tag: tip
201 201 user: test
202 202 date: Thu Jan 01 00:00:00 1970 +0000
203 203 summary: mess 1fd3b2fe7754 f
204 204
205 205
206 206 rollback should not work after a histedit
207 207 $ hg rollback
208 208 no rollback information available
209 209 [1]
210 210
211 211 $ cd ..
212 212 $ hg clone -qr0 r r0
213 213 $ cd r0
214 214 $ echo edit cb9a9f314b8b a > $EDITED
215 215 $ hg phase -fdr0
216 216 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 0 2>&1
217 217 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
218 218 adding a
219 219 abort: Make changes as needed, you may commit or record as needed now.
220 220 When you are finished, run hg histedit --continue to resume.
221 221 [255]
222 222 $ HGEDITOR=true hg histedit --continue
223 223 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
224 224 saved backup bundle to $TESTTMP/r0/.hg/strip-backup/cb9a9f314b8b-backup.hg (glob)
@@ -1,184 +1,184 b''
1 1 $ . "$TESTDIR/histedit-helpers.sh"
2 2
3 3 $ cat >> $HGRCPATH <<EOF
4 4 > [extensions]
5 5 > graphlog=
6 6 > histedit=
7 7 > EOF
8 8
9 9 $ initrepo ()
10 10 > {
11 11 > hg init $1
12 12 > cd $1
13 13 > for x in a b c d e f ; do
14 14 > echo $x$x$x$x$x > $x
15 15 > hg add $x
16 16 > done
17 17 > hg ci -m 'Initial commit'
18 18 > for x in a b c d e f ; do
19 19 > echo $x > $x
20 20 > hg ci -m $x
21 21 > done
22 22 > echo 'I can haz no commute' > e
23 23 > hg ci -m 'does not commute with e'
24 24 > cd ..
25 25 > }
26 26
27 27 $ initrepo r
28 28 $ cd r
29 29 Initial generation of the command files
30 30
31 31 $ EDITED="$TESTTMP/editedhistory"
32 32 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
33 33 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
34 34 $ hg log --template 'fold {node|short} {rev} {desc}\n' -r 7 >> $EDITED
35 35 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
36 36 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
37 37 $ cat $EDITED
38 38 pick 65a9a84f33fd 3 c
39 39 pick 00f1c5383965 4 d
40 40 fold 39522b764e3d 7 does not commute with e
41 41 pick 7b4e2f4b7bcd 5 e
42 42 pick 500cac37a696 6 f
43 43
44 44 log before edit
45 45 $ hg log --graph
46 46 @ changeset: 7:39522b764e3d
47 47 | tag: tip
48 48 | user: test
49 49 | date: Thu Jan 01 00:00:00 1970 +0000
50 50 | summary: does not commute with e
51 51 |
52 52 o changeset: 6:500cac37a696
53 53 | user: test
54 54 | date: Thu Jan 01 00:00:00 1970 +0000
55 55 | summary: f
56 56 |
57 57 o changeset: 5:7b4e2f4b7bcd
58 58 | user: test
59 59 | date: Thu Jan 01 00:00:00 1970 +0000
60 60 | summary: e
61 61 |
62 62 o changeset: 4:00f1c5383965
63 63 | user: test
64 64 | date: Thu Jan 01 00:00:00 1970 +0000
65 65 | summary: d
66 66 |
67 67 o changeset: 3:65a9a84f33fd
68 68 | user: test
69 69 | date: Thu Jan 01 00:00:00 1970 +0000
70 70 | summary: c
71 71 |
72 72 o changeset: 2:da6535b52e45
73 73 | user: test
74 74 | date: Thu Jan 01 00:00:00 1970 +0000
75 75 | summary: b
76 76 |
77 77 o changeset: 1:c1f09da44841
78 78 | user: test
79 79 | date: Thu Jan 01 00:00:00 1970 +0000
80 80 | summary: a
81 81 |
82 82 o changeset: 0:1715188a53c7
83 83 user: test
84 84 date: Thu Jan 01 00:00:00 1970 +0000
85 85 summary: Initial commit
86 86
87 87
88 88 edit the history
89 89 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 3 2>&1 | fixbundle
90 90 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 91 merging e
92 92 warning: conflicts during merge.
93 93 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
94 abort: Fix up the change and run hg histedit --continue
94 Fix up the change and run hg histedit --continue
95 95
96 96 fix up
97 97 $ echo 'I can haz no commute' > e
98 98 $ hg resolve --mark e
99 99 $ cat > cat.py <<EOF
100 100 > import sys
101 101 > print open(sys.argv[1]).read()
102 102 > print
103 103 > print
104 104 > EOF
105 105 $ HGEDITOR="python cat.py" hg histedit --continue 2>&1 | fixbundle | grep -v '2 files removed'
106 106 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 107 d
108 108 ***
109 109 does not commute with e
110 110
111 111
112 112
113 113 HG: Enter commit message. Lines beginning with 'HG:' are removed.
114 114 HG: Leave message empty to abort commit.
115 115 HG: --
116 116 HG: user: test
117 117 HG: branch 'default'
118 118 HG: changed d
119 119 HG: changed e
120 120
121 121
122 122
123 123 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
124 124 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
125 125 merging e
126 126 warning: conflicts during merge.
127 127 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
128 abort: Fix up the change and run hg histedit --continue
128 Fix up the change and run hg histedit --continue
129 129
130 130 just continue this time
131 131 $ hg revert -r 'p1()' e
132 132 $ hg resolve --mark e
133 133 $ hg histedit --continue 2>&1 | fixbundle
134 134 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
135 135 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
136 136
137 137 log after edit
138 138 $ hg log --graph
139 139 @ changeset: 5:d9cf42e54966
140 140 | tag: tip
141 141 | user: test
142 142 | date: Thu Jan 01 00:00:00 1970 +0000
143 143 | summary: f
144 144 |
145 145 o changeset: 4:10486af2e984
146 146 | user: test
147 147 | date: Thu Jan 01 00:00:00 1970 +0000
148 148 | summary: d
149 149 |
150 150 o changeset: 3:65a9a84f33fd
151 151 | user: test
152 152 | date: Thu Jan 01 00:00:00 1970 +0000
153 153 | summary: c
154 154 |
155 155 o changeset: 2:da6535b52e45
156 156 | user: test
157 157 | date: Thu Jan 01 00:00:00 1970 +0000
158 158 | summary: b
159 159 |
160 160 o changeset: 1:c1f09da44841
161 161 | user: test
162 162 | date: Thu Jan 01 00:00:00 1970 +0000
163 163 | summary: a
164 164 |
165 165 o changeset: 0:1715188a53c7
166 166 user: test
167 167 date: Thu Jan 01 00:00:00 1970 +0000
168 168 summary: Initial commit
169 169
170 170
171 171 contents of e
172 172 $ hg cat e
173 173 I can haz no commute
174 174
175 175 manifest
176 176 $ hg manifest
177 177 a
178 178 b
179 179 c
180 180 d
181 181 e
182 182 f
183 183
184 184 $ cd ..
@@ -1,318 +1,318 b''
1 1 $ . "$TESTDIR/histedit-helpers.sh"
2 2
3 3 $ cat >> $HGRCPATH <<EOF
4 4 > [extensions]
5 5 > graphlog=
6 6 > histedit=
7 7 > EOF
8 8
9 9 $ EDITED="$TESTTMP/editedhistory"
10 10 $ cat > $EDITED <<EOF
11 11 > pick e860deea161a e
12 12 > pick 652413bf663e f
13 13 > fold 177f92b77385 c
14 14 > pick 055a42cdd887 d
15 15 > EOF
16 16 $ initrepo ()
17 17 > {
18 18 > hg init r
19 19 > cd r
20 20 > for x in a b c d e f ; do
21 21 > echo $x > $x
22 22 > hg add $x
23 23 > hg ci -m $x
24 24 > done
25 25 > }
26 26
27 27 $ initrepo
28 28
29 29 log before edit
30 30 $ hg log --graph
31 31 @ changeset: 5:652413bf663e
32 32 | tag: tip
33 33 | user: test
34 34 | date: Thu Jan 01 00:00:00 1970 +0000
35 35 | summary: f
36 36 |
37 37 o changeset: 4:e860deea161a
38 38 | user: test
39 39 | date: Thu Jan 01 00:00:00 1970 +0000
40 40 | summary: e
41 41 |
42 42 o changeset: 3:055a42cdd887
43 43 | user: test
44 44 | date: Thu Jan 01 00:00:00 1970 +0000
45 45 | summary: d
46 46 |
47 47 o changeset: 2:177f92b77385
48 48 | user: test
49 49 | date: Thu Jan 01 00:00:00 1970 +0000
50 50 | summary: c
51 51 |
52 52 o changeset: 1:d2ae7f538514
53 53 | user: test
54 54 | date: Thu Jan 01 00:00:00 1970 +0000
55 55 | summary: b
56 56 |
57 57 o changeset: 0:cb9a9f314b8b
58 58 user: test
59 59 date: Thu Jan 01 00:00:00 1970 +0000
60 60 summary: a
61 61
62 62
63 63 edit the history
64 64 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
65 65 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
66 66 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
67 67 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
68 68 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
69 69 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 70 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
71 71 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
72 72
73 73 log after edit
74 74 $ hg log --graph
75 75 @ changeset: 4:7e0a290363ed
76 76 | tag: tip
77 77 | user: test
78 78 | date: Thu Jan 01 00:00:00 1970 +0000
79 79 | summary: d
80 80 |
81 81 o changeset: 3:5e24935bad3d
82 82 | user: test
83 83 | date: Thu Jan 01 00:00:00 1970 +0000
84 84 | summary: pick e860deea161a e
85 85 |
86 86 o changeset: 2:ee283cb5f2d5
87 87 | user: test
88 88 | date: Thu Jan 01 00:00:00 1970 +0000
89 89 | summary: e
90 90 |
91 91 o changeset: 1:d2ae7f538514
92 92 | user: test
93 93 | date: Thu Jan 01 00:00:00 1970 +0000
94 94 | summary: b
95 95 |
96 96 o changeset: 0:cb9a9f314b8b
97 97 user: test
98 98 date: Thu Jan 01 00:00:00 1970 +0000
99 99 summary: a
100 100
101 101
102 102 post-fold manifest
103 103 $ hg manifest
104 104 a
105 105 b
106 106 c
107 107 d
108 108 e
109 109 f
110 110
111 111
112 112 check histedit_source
113 113
114 114 $ hg log --debug --rev 3
115 115 changeset: 3:5e24935bad3d5a4486de3b90f233e991465ced72
116 116 phase: draft
117 117 parent: 2:ee283cb5f2d5955443f23a27b697a04339e9a39a
118 118 parent: -1:0000000000000000000000000000000000000000
119 119 manifest: 3:81eede616954057198ead0b2c73b41d1f392829a
120 120 user: test
121 121 date: Thu Jan 01 00:00:00 1970 +0000
122 122 files+: c f
123 123 extra: branch=default
124 124 extra: histedit_source=a4f7421b80f79fcc59fff01bcbf4a53d127dd6d3,177f92b773850b59254aa5e923436f921b55483b
125 125 description:
126 126 pick e860deea161a e
127 127 pick 652413bf663e f
128 128 fold 177f92b77385 c
129 129 pick 055a42cdd887 d
130 130
131 131
132 132
133 133 $ cd ..
134 134
135 135 folding and creating no new change doesn't break:
136 136 $ mkdir fold-to-empty-test
137 137 $ cd fold-to-empty-test
138 138 $ hg init
139 139 $ printf "1\n2\n3\n" > file
140 140 $ hg add file
141 141 $ hg commit -m '1+2+3'
142 142 $ echo 4 >> file
143 143 $ hg commit -m '+4'
144 144 $ echo 5 >> file
145 145 $ hg commit -m '+5'
146 146 $ echo 6 >> file
147 147 $ hg commit -m '+6'
148 148 $ hg log --graph
149 149 @ changeset: 3:251d831eeec5
150 150 | tag: tip
151 151 | user: test
152 152 | date: Thu Jan 01 00:00:00 1970 +0000
153 153 | summary: +6
154 154 |
155 155 o changeset: 2:888f9082bf99
156 156 | user: test
157 157 | date: Thu Jan 01 00:00:00 1970 +0000
158 158 | summary: +5
159 159 |
160 160 o changeset: 1:617f94f13c0f
161 161 | user: test
162 162 | date: Thu Jan 01 00:00:00 1970 +0000
163 163 | summary: +4
164 164 |
165 165 o changeset: 0:0189ba417d34
166 166 user: test
167 167 date: Thu Jan 01 00:00:00 1970 +0000
168 168 summary: 1+2+3
169 169
170 170
171 171 $ cat > editor.py <<EOF
172 172 > import re, sys
173 173 > rules = sys.argv[1]
174 174 > data = open(rules).read()
175 175 > data = re.sub(r'pick ([0-9a-f]{12} 2 \+5)', r'drop \1', data)
176 176 > data = re.sub(r'pick ([0-9a-f]{12} 2 \+6)', r'fold \1', data)
177 177 > open(rules, 'w').write(data)
178 178 > EOF
179 179
180 180 $ HGEDITOR='python editor.py' hg histedit 1
181 181 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
182 182 merging file
183 183 warning: conflicts during merge.
184 184 merging file incomplete! (edit conflicts, then use 'hg resolve --mark')
185 abort: Fix up the change and run hg histedit --continue
185 Fix up the change and run hg histedit --continue
186 186 [255]
187 187 There were conflicts, we keep P1 content. This
188 188 should effectively drop the changes from +6.
189 189 $ hg status
190 190 M file
191 191 ? editor.py
192 192 ? file.orig
193 193 $ hg resolve -l
194 194 U file
195 195 $ hg revert -r 'p1()' file
196 196 $ hg resolve --mark file
197 197 $ hg histedit --continue
198 198 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
199 199 saved backup bundle to $TESTTMP/*-backup.hg (glob)
200 200 $ hg log --graph
201 201 @ changeset: 1:617f94f13c0f
202 202 | tag: tip
203 203 | user: test
204 204 | date: Thu Jan 01 00:00:00 1970 +0000
205 205 | summary: +4
206 206 |
207 207 o changeset: 0:0189ba417d34
208 208 user: test
209 209 date: Thu Jan 01 00:00:00 1970 +0000
210 210 summary: 1+2+3
211 211
212 212
213 213 $ cd ..
214 214
215 215 Test corner case where folded revision is separated from its parent by a
216 216 dropped revision.
217 217
218 218
219 219 $ hg init fold-with-dropped
220 220 $ cd fold-with-dropped
221 221 $ printf "1\n2\n3\n" > file
222 222 $ hg commit -Am '1+2+3'
223 223 adding file
224 224 $ echo 4 >> file
225 225 $ hg commit -m '+4'
226 226 $ echo 5 >> file
227 227 $ hg commit -m '+5'
228 228 $ echo 6 >> file
229 229 $ hg commit -m '+6'
230 230 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n'
231 231 @ 3:251d831eeec5 +6
232 232 |
233 233 o 2:888f9082bf99 +5
234 234 |
235 235 o 1:617f94f13c0f +4
236 236 |
237 237 o 0:0189ba417d34 1+2+3
238 238
239 239 $ EDITED="$TESTTMP/editcommands"
240 240 $ cat > $EDITED <<EOF
241 241 > pick 617f94f13c0f 1 +4
242 242 > drop 888f9082bf99 2 +5
243 243 > fold 251d831eeec5 3 +6
244 244 > EOF
245 245 $ HGEDITOR="cat $EDITED >" hg histedit 1
246 246 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
247 247 merging file
248 248 warning: conflicts during merge.
249 249 merging file incomplete! (edit conflicts, then use 'hg resolve --mark')
250 abort: Fix up the change and run hg histedit --continue
250 Fix up the change and run hg histedit --continue
251 251 [255]
252 252 $ cat > file << EOF
253 253 > 1
254 254 > 2
255 255 > 3
256 256 > 4
257 257 > 5
258 258 > EOF
259 259 $ hg resolve --mark file
260 260 $ hg commit -m '+5.2'
261 261 created new head
262 262 $ echo 6 >> file
263 263 $ HGEDITOR=cat hg histedit --continue
264 264 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
265 265 +4
266 266 ***
267 267 +5.2
268 268 ***
269 269 +6
270 270
271 271
272 272
273 273 HG: Enter commit message. Lines beginning with 'HG:' are removed.
274 274 HG: Leave message empty to abort commit.
275 275 HG: --
276 276 HG: user: test
277 277 HG: branch 'default'
278 278 HG: changed file
279 279 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 280 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
281 281 saved backup bundle to $TESTTMP/fold-with-dropped/.hg/strip-backup/617f94f13c0f-backup.hg (glob)
282 282 $ hg log -G
283 283 @ changeset: 1:10c647b2cdd5
284 284 | tag: tip
285 285 | user: test
286 286 | date: Thu Jan 01 00:00:00 1970 +0000
287 287 | summary: +4
288 288 |
289 289 o changeset: 0:0189ba417d34
290 290 user: test
291 291 date: Thu Jan 01 00:00:00 1970 +0000
292 292 summary: 1+2+3
293 293
294 294 $ hg export tip
295 295 # HG changeset patch
296 296 # User test
297 297 # Date 0 0
298 298 # Thu Jan 01 00:00:00 1970 +0000
299 299 # Node ID 10c647b2cdd54db0603ecb99b2ff5ce66d5a5323
300 300 # Parent 0189ba417d34df9dda55f88b637dcae9917b5964
301 301 +4
302 302 ***
303 303 +5.2
304 304 ***
305 305 +6
306 306
307 307 diff -r 0189ba417d34 -r 10c647b2cdd5 file
308 308 --- a/file Thu Jan 01 00:00:00 1970 +0000
309 309 +++ b/file Thu Jan 01 00:00:00 1970 +0000
310 310 @@ -1,3 +1,6 @@
311 311 1
312 312 2
313 313 3
314 314 +4
315 315 +5
316 316 +6
317 317 $ cd ..
318 318
@@ -1,191 +1,191 b''
1 1 test for old histedit issue #6:
2 2 editing a changeset without any actual change would corrupt the repository
3 3
4 4 $ . "$TESTDIR/histedit-helpers.sh"
5 5
6 6 $ cat >> $HGRCPATH <<EOF
7 7 > [extensions]
8 8 > graphlog=
9 9 > histedit=
10 10 > EOF
11 11
12 12 $ initrepo ()
13 13 > {
14 14 > dir="$1"
15 15 > comment="$2"
16 16 > if [ -n "${comment}" ]; then
17 17 > echo % ${comment}
18 18 > echo % ${comment} | sed 's:.:-:g'
19 19 > fi
20 20 > hg init ${dir}
21 21 > cd ${dir}
22 22 > for x in a b c d e f ; do
23 23 > echo $x > $x
24 24 > hg add $x
25 25 > hg ci -m $x
26 26 > done
27 27 > cd ..
28 28 > }
29 29
30 30 $ geneditor ()
31 31 > {
32 32 > # generate an editor script for selecting changesets to be edited
33 33 > choice=$1 # changesets that should be edited (using sed line ranges)
34 34 > cat <<EOF | sed 's:^....::'
35 35 > # editing the rules, replacing 'pick' with 'edit' for the chosen lines
36 36 > sed '${choice}s:^pick:edit:' "\$1" > "\${1}.tmp"
37 37 > mv "\${1}.tmp" "\$1"
38 38 > # displaying the resulting rules, minus comments and empty lines
39 39 > sed '/^#/d;/^$/d;s:^:| :' "\$1" >&2
40 40 > EOF
41 41 > }
42 42
43 43 $ startediting ()
44 44 > {
45 45 > # begin an editing session
46 46 > choice="$1" # changesets that should be edited
47 47 > number="$2" # number of changesets considered (from tip)
48 48 > comment="$3"
49 49 > geneditor "${choice}" > edit.sh
50 50 > echo % start editing the history ${comment}
51 51 > HGEDITOR="sh ./edit.sh" hg histedit -- -${number} 2>&1 | fixbundle
52 52 > }
53 53
54 54 $ continueediting ()
55 55 > {
56 56 > # continue an edit already in progress
57 57 > editor="$1" # message editor when finalizing editing
58 58 > comment="$2"
59 59 > echo % finalize changeset editing ${comment}
60 60 > HGEDITOR=${editor} hg histedit --continue 2>&1 | fixbundle
61 61 > }
62 62
63 63 $ graphlog ()
64 64 > {
65 65 > comment="${1:-log}"
66 66 > echo % "${comment}"
67 67 > hg glog --template '{rev} {node} \"{desc|firstline}\"\n'
68 68 > }
69 69
70 70
71 71 $ initrepo r1 "test editing with no change"
72 72 % test editing with no change
73 73 -----------------------------
74 74 $ cd r1
75 75 $ graphlog "log before editing"
76 76 % log before editing
77 77 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
78 78 |
79 79 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
80 80 |
81 81 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
82 82 |
83 83 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
84 84 |
85 85 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
86 86 |
87 87 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
88 88
89 89 $ startediting 2 3 "(not changing anything)" # edit the 2nd of 3 changesets
90 90 % start editing the history (not changing anything)
91 91 | pick 055a42cdd887 3 d
92 92 | edit e860deea161a 4 e
93 93 | pick 652413bf663e 5 f
94 94 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
95 abort: Make changes as needed, you may commit or record as needed now.
95 Make changes as needed, you may commit or record as needed now.
96 96 When you are finished, run hg histedit --continue to resume.
97 97 $ continueediting true "(leaving commit message unaltered)"
98 98 % finalize changeset editing (leaving commit message unaltered)
99 99 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 100 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
101 101
102 102
103 103 check state of working copy
104 104 $ hg id
105 105 794fe033d0a0 tip
106 106
107 107 $ graphlog "log after history editing"
108 108 % log after history editing
109 109 @ 5 794fe033d0a030f8df77c5de945fca35c9181c30 "f"
110 110 |
111 111 o 4 04d2fab980779f332dec458cc944f28de8b43435 "e"
112 112 |
113 113 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
114 114 |
115 115 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
116 116 |
117 117 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
118 118 |
119 119 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
120 120
121 121
122 122 $ cd ..
123 123
124 124 $ initrepo r2 "test editing with no change, then abort"
125 125 % test editing with no change, then abort
126 126 -----------------------------------------
127 127 $ cd r2
128 128 $ graphlog "log before editing"
129 129 % log before editing
130 130 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
131 131 |
132 132 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
133 133 |
134 134 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
135 135 |
136 136 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
137 137 |
138 138 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
139 139 |
140 140 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
141 141
142 142 $ startediting 1,2 3 "(not changing anything)" # edit the 1st two of 3 changesets
143 143 % start editing the history (not changing anything)
144 144 | edit 055a42cdd887 3 d
145 145 | edit e860deea161a 4 e
146 146 | pick 652413bf663e 5 f
147 147 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
148 abort: Make changes as needed, you may commit or record as needed now.
148 Make changes as needed, you may commit or record as needed now.
149 149 When you are finished, run hg histedit --continue to resume.
150 150 $ continueediting true "(leaving commit message unaltered)"
151 151 % finalize changeset editing (leaving commit message unaltered)
152 152 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
153 abort: Make changes as needed, you may commit or record as needed now.
153 Make changes as needed, you may commit or record as needed now.
154 154 When you are finished, run hg histedit --continue to resume.
155 155 $ graphlog "log after first edit"
156 156 % log after first edit
157 157 @ 6 e5ae3ca2f1ffdbd89ec41ebc273a231f7c3022f2 "d"
158 158 |
159 159 | o 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
160 160 | |
161 161 | o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
162 162 | |
163 163 | o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
164 164 |/
165 165 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
166 166 |
167 167 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
168 168 |
169 169 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
170 170
171 171
172 172 abort editing session
173 173 $ hg histedit --abort 2>&1 | fixbundle
174 174 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
175 175
176 176 $ graphlog "log after abort"
177 177 % log after abort
178 178 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
179 179 |
180 180 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
181 181 |
182 182 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
183 183 |
184 184 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
185 185 |
186 186 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
187 187 |
188 188 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
189 189
190 190
191 191 $ cd ..
@@ -1,129 +1,129 b''
1 1 $ . "$TESTDIR/histedit-helpers.sh"
2 2
3 3 $ cat >> $HGRCPATH <<EOF
4 4 > [extensions]
5 5 > graphlog=
6 6 > histedit=
7 7 > EOF
8 8
9 9 $ EDITED="$TESTTMP/editedhistory"
10 10 $ cat > $EDITED <<EOF
11 11 > pick 177f92b77385 c
12 12 > pick 055a42cdd887 d
13 13 > pick bfa474341cc9 does not commute with e
14 14 > pick e860deea161a e
15 15 > pick 652413bf663e f
16 16 > EOF
17 17 $ initrepo ()
18 18 > {
19 19 > hg init r
20 20 > cd r
21 21 > for x in a b c d e f ; do
22 22 > echo $x > $x
23 23 > hg add $x
24 24 > hg ci -m $x
25 25 > done
26 26 > echo a >> e
27 27 > hg ci -m 'does not commute with e'
28 28 > cd ..
29 29 > }
30 30
31 31 $ initrepo
32 32 $ cd r
33 33
34 34 log before edit
35 35 $ hg log --graph
36 36 @ changeset: 6:bfa474341cc9
37 37 | tag: tip
38 38 | user: test
39 39 | date: Thu Jan 01 00:00:00 1970 +0000
40 40 | summary: does not commute with e
41 41 |
42 42 o changeset: 5:652413bf663e
43 43 | user: test
44 44 | date: Thu Jan 01 00:00:00 1970 +0000
45 45 | summary: f
46 46 |
47 47 o changeset: 4:e860deea161a
48 48 | user: test
49 49 | date: Thu Jan 01 00:00:00 1970 +0000
50 50 | summary: e
51 51 |
52 52 o changeset: 3:055a42cdd887
53 53 | user: test
54 54 | date: Thu Jan 01 00:00:00 1970 +0000
55 55 | summary: d
56 56 |
57 57 o changeset: 2:177f92b77385
58 58 | user: test
59 59 | date: Thu Jan 01 00:00:00 1970 +0000
60 60 | summary: c
61 61 |
62 62 o changeset: 1:d2ae7f538514
63 63 | user: test
64 64 | date: Thu Jan 01 00:00:00 1970 +0000
65 65 | summary: b
66 66 |
67 67 o changeset: 0:cb9a9f314b8b
68 68 user: test
69 69 date: Thu Jan 01 00:00:00 1970 +0000
70 70 summary: a
71 71
72 72
73 73 edit the history
74 74 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
75 75 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
76 76 remote changed e which local deleted
77 77 use (c)hanged version or leave (d)eleted? c
78 78 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 79 merging e
80 80 warning: conflicts during merge.
81 81 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
82 abort: Fix up the change and run hg histedit --continue
82 Fix up the change and run hg histedit --continue
83 83
84 84
85 85 abort the edit
86 86 $ hg histedit --abort 2>&1 | fixbundle
87 87 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 88
89 89 log after abort
90 90 $ hg resolve -l
91 91 $ hg log --graph
92 92 @ changeset: 6:bfa474341cc9
93 93 | tag: tip
94 94 | user: test
95 95 | date: Thu Jan 01 00:00:00 1970 +0000
96 96 | summary: does not commute with e
97 97 |
98 98 o changeset: 5:652413bf663e
99 99 | user: test
100 100 | date: Thu Jan 01 00:00:00 1970 +0000
101 101 | summary: f
102 102 |
103 103 o changeset: 4:e860deea161a
104 104 | user: test
105 105 | date: Thu Jan 01 00:00:00 1970 +0000
106 106 | summary: e
107 107 |
108 108 o changeset: 3:055a42cdd887
109 109 | user: test
110 110 | date: Thu Jan 01 00:00:00 1970 +0000
111 111 | summary: d
112 112 |
113 113 o changeset: 2:177f92b77385
114 114 | user: test
115 115 | date: Thu Jan 01 00:00:00 1970 +0000
116 116 | summary: c
117 117 |
118 118 o changeset: 1:d2ae7f538514
119 119 | user: test
120 120 | date: Thu Jan 01 00:00:00 1970 +0000
121 121 | summary: b
122 122 |
123 123 o changeset: 0:cb9a9f314b8b
124 124 user: test
125 125 date: Thu Jan 01 00:00:00 1970 +0000
126 126 summary: a
127 127
128 128
129 129 $ cd ..
@@ -1,295 +1,295 b''
1 1 $ . "$TESTDIR/histedit-helpers.sh"
2 2
3 3 $ cat >> $HGRCPATH <<EOF
4 4 > [extensions]
5 5 > graphlog=
6 6 > histedit=
7 7 > EOF
8 8
9 9 $ initrepo ()
10 10 > {
11 11 > hg init $1
12 12 > cd $1
13 13 > for x in a b c d e f ; do
14 14 > echo $x$x$x$x$x > $x
15 15 > hg add $x
16 16 > done
17 17 > hg ci -m 'Initial commit'
18 18 > for x in a b c d e f ; do
19 19 > echo $x > $x
20 20 > hg ci -m $x
21 21 > done
22 22 > echo 'I can haz no commute' > e
23 23 > hg ci -m 'does not commute with e'
24 24 > cd ..
25 25 > }
26 26
27 27 $ initrepo r1
28 28 $ cd r1
29 29
30 30 Initial generation of the command files
31 31
32 32 $ EDITED="$TESTTMP/editedhistory"
33 33 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
34 34 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
35 35 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 7 >> $EDITED
36 36 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
37 37 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
38 38 $ cat $EDITED
39 39 pick 65a9a84f33fd 3 c
40 40 pick 00f1c5383965 4 d
41 41 pick 39522b764e3d 7 does not commute with e
42 42 pick 7b4e2f4b7bcd 5 e
43 43 pick 500cac37a696 6 f
44 44
45 45 log before edit
46 46 $ hg log --graph
47 47 @ changeset: 7:39522b764e3d
48 48 | tag: tip
49 49 | user: test
50 50 | date: Thu Jan 01 00:00:00 1970 +0000
51 51 | summary: does not commute with e
52 52 |
53 53 o changeset: 6:500cac37a696
54 54 | user: test
55 55 | date: Thu Jan 01 00:00:00 1970 +0000
56 56 | summary: f
57 57 |
58 58 o changeset: 5:7b4e2f4b7bcd
59 59 | user: test
60 60 | date: Thu Jan 01 00:00:00 1970 +0000
61 61 | summary: e
62 62 |
63 63 o changeset: 4:00f1c5383965
64 64 | user: test
65 65 | date: Thu Jan 01 00:00:00 1970 +0000
66 66 | summary: d
67 67 |
68 68 o changeset: 3:65a9a84f33fd
69 69 | user: test
70 70 | date: Thu Jan 01 00:00:00 1970 +0000
71 71 | summary: c
72 72 |
73 73 o changeset: 2:da6535b52e45
74 74 | user: test
75 75 | date: Thu Jan 01 00:00:00 1970 +0000
76 76 | summary: b
77 77 |
78 78 o changeset: 1:c1f09da44841
79 79 | user: test
80 80 | date: Thu Jan 01 00:00:00 1970 +0000
81 81 | summary: a
82 82 |
83 83 o changeset: 0:1715188a53c7
84 84 user: test
85 85 date: Thu Jan 01 00:00:00 1970 +0000
86 86 summary: Initial commit
87 87
88 88
89 89 edit the history
90 90 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 3 2>&1 | fixbundle
91 91 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 92 merging e
93 93 warning: conflicts during merge.
94 94 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
95 abort: Fix up the change and run hg histedit --continue
95 Fix up the change and run hg histedit --continue
96 96
97 97 abort the edit
98 98 $ hg histedit --abort 2>&1 | fixbundle
99 99 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 100
101 101
102 102 second edit set
103 103
104 104 $ hg log --graph
105 105 @ changeset: 7:39522b764e3d
106 106 | tag: tip
107 107 | user: test
108 108 | date: Thu Jan 01 00:00:00 1970 +0000
109 109 | summary: does not commute with e
110 110 |
111 111 o changeset: 6:500cac37a696
112 112 | user: test
113 113 | date: Thu Jan 01 00:00:00 1970 +0000
114 114 | summary: f
115 115 |
116 116 o changeset: 5:7b4e2f4b7bcd
117 117 | user: test
118 118 | date: Thu Jan 01 00:00:00 1970 +0000
119 119 | summary: e
120 120 |
121 121 o changeset: 4:00f1c5383965
122 122 | user: test
123 123 | date: Thu Jan 01 00:00:00 1970 +0000
124 124 | summary: d
125 125 |
126 126 o changeset: 3:65a9a84f33fd
127 127 | user: test
128 128 | date: Thu Jan 01 00:00:00 1970 +0000
129 129 | summary: c
130 130 |
131 131 o changeset: 2:da6535b52e45
132 132 | user: test
133 133 | date: Thu Jan 01 00:00:00 1970 +0000
134 134 | summary: b
135 135 |
136 136 o changeset: 1:c1f09da44841
137 137 | user: test
138 138 | date: Thu Jan 01 00:00:00 1970 +0000
139 139 | summary: a
140 140 |
141 141 o changeset: 0:1715188a53c7
142 142 user: test
143 143 date: Thu Jan 01 00:00:00 1970 +0000
144 144 summary: Initial commit
145 145
146 146
147 147 edit the history
148 148 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 3 2>&1 | fixbundle
149 149 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 150 merging e
151 151 warning: conflicts during merge.
152 152 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
153 abort: Fix up the change and run hg histedit --continue
153 Fix up the change and run hg histedit --continue
154 154
155 155 fix up
156 156 $ echo 'I can haz no commute' > e
157 157 $ hg resolve --mark e
158 158 $ hg histedit --continue 2>&1 | fixbundle
159 159 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 160 merging e
161 161 warning: conflicts during merge.
162 162 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
163 abort: Fix up the change and run hg histedit --continue
163 Fix up the change and run hg histedit --continue
164 164
165 165 This failure is caused by 7b4e2f4b7bcd "e" not rebasing the non commutative
166 166 former children.
167 167
168 168 just continue this time
169 169 $ hg revert -r 'p1()' e
170 170 $ hg resolve --mark e
171 171 $ hg histedit --continue 2>&1 | fixbundle
172 172 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
173 173 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
174 174
175 175 log after edit
176 176 $ hg log --graph
177 177 @ changeset: 6:7efe1373e4bc
178 178 | tag: tip
179 179 | user: test
180 180 | date: Thu Jan 01 00:00:00 1970 +0000
181 181 | summary: f
182 182 |
183 183 o changeset: 5:e334d87a1e55
184 184 | user: test
185 185 | date: Thu Jan 01 00:00:00 1970 +0000
186 186 | summary: does not commute with e
187 187 |
188 188 o changeset: 4:00f1c5383965
189 189 | user: test
190 190 | date: Thu Jan 01 00:00:00 1970 +0000
191 191 | summary: d
192 192 |
193 193 o changeset: 3:65a9a84f33fd
194 194 | user: test
195 195 | date: Thu Jan 01 00:00:00 1970 +0000
196 196 | summary: c
197 197 |
198 198 o changeset: 2:da6535b52e45
199 199 | user: test
200 200 | date: Thu Jan 01 00:00:00 1970 +0000
201 201 | summary: b
202 202 |
203 203 o changeset: 1:c1f09da44841
204 204 | user: test
205 205 | date: Thu Jan 01 00:00:00 1970 +0000
206 206 | summary: a
207 207 |
208 208 o changeset: 0:1715188a53c7
209 209 user: test
210 210 date: Thu Jan 01 00:00:00 1970 +0000
211 211 summary: Initial commit
212 212
213 213
214 214 start over
215 215
216 216 $ cd ..
217 217
218 218 $ initrepo r2
219 219 $ cd r2
220 220 $ rm $EDITED
221 221 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
222 222 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
223 223 $ hg log --template 'mess {node|short} {rev} {desc}\n' -r 7 >> $EDITED
224 224 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
225 225 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
226 226 $ cat $EDITED
227 227 pick 65a9a84f33fd 3 c
228 228 pick 00f1c5383965 4 d
229 229 mess 39522b764e3d 7 does not commute with e
230 230 pick 7b4e2f4b7bcd 5 e
231 231 pick 500cac37a696 6 f
232 232
233 233 edit the history, this time with a fold action
234 234 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 3 2>&1 | fixbundle
235 235 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
236 236 merging e
237 237 warning: conflicts during merge.
238 238 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
239 abort: Fix up the change and run hg histedit --continue
239 Fix up the change and run hg histedit --continue
240 240
241 241 $ echo 'I can haz no commute' > e
242 242 $ hg resolve --mark e
243 243 $ HGEDITOR="cat \"$EDITED\" > " hg histedit --continue 2>&1 | fixbundle
244 244 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
245 245 merging e
246 246 warning: conflicts during merge.
247 247 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
248 abort: Fix up the change and run hg histedit --continue
248 Fix up the change and run hg histedit --continue
249 249 second edit also fails, but just continue
250 250 $ hg revert -r 'p1()' e
251 251 $ hg resolve --mark e
252 252 $ hg histedit --continue 2>&1 | fixbundle
253 253 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
254 254 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
255 255
256 256 post message fix
257 257 $ hg log --graph
258 258 @ changeset: 6:521c4c32c5e2
259 259 | tag: tip
260 260 | user: test
261 261 | date: Thu Jan 01 00:00:00 1970 +0000
262 262 | summary: f
263 263 |
264 264 o changeset: 5:f4f088e8adf6
265 265 | user: test
266 266 | date: Thu Jan 01 00:00:00 1970 +0000
267 267 | summary: pick 65a9a84f33fd 3 c
268 268 |
269 269 o changeset: 4:00f1c5383965
270 270 | user: test
271 271 | date: Thu Jan 01 00:00:00 1970 +0000
272 272 | summary: d
273 273 |
274 274 o changeset: 3:65a9a84f33fd
275 275 | user: test
276 276 | date: Thu Jan 01 00:00:00 1970 +0000
277 277 | summary: c
278 278 |
279 279 o changeset: 2:da6535b52e45
280 280 | user: test
281 281 | date: Thu Jan 01 00:00:00 1970 +0000
282 282 | summary: b
283 283 |
284 284 o changeset: 1:c1f09da44841
285 285 | user: test
286 286 | date: Thu Jan 01 00:00:00 1970 +0000
287 287 | summary: a
288 288 |
289 289 o changeset: 0:1715188a53c7
290 290 user: test
291 291 date: Thu Jan 01 00:00:00 1970 +0000
292 292 summary: Initial commit
293 293
294 294
295 295 $ cd ..
@@ -1,454 +1,454 b''
1 1 $ . "$TESTDIR/histedit-helpers.sh"
2 2
3 3 Enable obsolete
4 4
5 5 $ cat > ${TESTTMP}/obs.py << EOF
6 6 > import mercurial.obsolete
7 7 > mercurial.obsolete._enabled = True
8 8 > EOF
9 9
10 10 $ cat >> $HGRCPATH << EOF
11 11 > [ui]
12 12 > logtemplate= {rev}:{node|short} {desc|firstline}
13 13 > [phases]
14 14 > publish=False
15 15 > [extensions]'
16 16 > histedit=
17 17 > rebase=
18 18 >
19 19 > obs=${TESTTMP}/obs.py
20 20 > EOF
21 21
22 22 $ hg init base
23 23 $ cd base
24 24
25 25 $ for x in a b c d e f ; do
26 26 > echo $x > $x
27 27 > hg add $x
28 28 > hg ci -m $x
29 29 > done
30 30
31 31 $ hg log --graph
32 32 @ 5:652413bf663e f
33 33 |
34 34 o 4:e860deea161a e
35 35 |
36 36 o 3:055a42cdd887 d
37 37 |
38 38 o 2:177f92b77385 c
39 39 |
40 40 o 1:d2ae7f538514 b
41 41 |
42 42 o 0:cb9a9f314b8b a
43 43
44 44
45 45 $ HGEDITOR=cat hg histedit 1
46 46 pick d2ae7f538514 1 b
47 47 pick 177f92b77385 2 c
48 48 pick 055a42cdd887 3 d
49 49 pick e860deea161a 4 e
50 50 pick 652413bf663e 5 f
51 51
52 52 # Edit history between d2ae7f538514 and 652413bf663e
53 53 #
54 54 # Commands:
55 55 # p, pick = use commit
56 56 # e, edit = use commit, but stop for amending
57 57 # f, fold = use commit, but fold into previous commit (combines N and N-1)
58 58 # d, drop = remove commit from history
59 59 # m, mess = edit message without changing commit content
60 60 #
61 61 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 62 $ cat > commands.txt <<EOF
63 63 > pick 177f92b77385 2 c
64 64 > drop d2ae7f538514 1 b
65 65 > pick 055a42cdd887 3 d
66 66 > fold e860deea161a 4 e
67 67 > pick 652413bf663e 5 f
68 68 > EOF
69 69 $ hg histedit 1 --commands commands.txt --verbose | grep histedit
70 70 saved backup bundle to $TESTTMP/base/.hg/strip-backup/96e494a2d553-backup.hg (glob)
71 71 $ hg log --graph --hidden
72 72 @ 8:cacdfd884a93 f
73 73 |
74 74 o 7:59d9f330561f d
75 75 |
76 76 o 6:b346ab9a313d c
77 77 |
78 78 | x 5:652413bf663e f
79 79 | |
80 80 | x 4:e860deea161a e
81 81 | |
82 82 | x 3:055a42cdd887 d
83 83 | |
84 84 | x 2:177f92b77385 c
85 85 | |
86 86 | x 1:d2ae7f538514 b
87 87 |/
88 88 o 0:cb9a9f314b8b a
89 89
90 90 $ hg debugobsolete
91 91 d2ae7f538514cd87c17547b0de4cea71fe1af9fb 0 {'date': '* *', 'user': 'test'} (glob)
92 92 177f92b773850b59254aa5e923436f921b55483b b346ab9a313db8537ecf96fca3ca3ca984ef3bd7 0 {'date': '* *', 'user': 'test'} (glob)
93 93 055a42cdd88768532f9cf79daa407fc8d138de9b 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 {'date': '* *', 'user': 'test'} (glob)
94 94 e860deea161a2f77de56603b340ebbb4536308ae 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 {'date': '* *', 'user': 'test'} (glob)
95 95 652413bf663ef2a641cab26574e46d5f5a64a55a cacdfd884a9321ec4e1de275ef3949fa953a1f83 0 {'date': '* *', 'user': 'test'} (glob)
96 96
97 97
98 98 Ensure hidden revision does not prevent histedit
99 99 -------------------------------------------------
100 100
101 101 create an hidden revision
102 102
103 103 $ cat > commands.txt <<EOF
104 104 > pick b346ab9a313d 6 c
105 105 > drop 59d9f330561f 7 d
106 106 > pick cacdfd884a93 8 f
107 107 > EOF
108 108 $ hg histedit 6 --commands commands.txt
109 109 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
110 110 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
111 111 $ hg log --graph
112 112 @ 9:c13eb81022ca f
113 113 |
114 114 o 6:b346ab9a313d c
115 115 |
116 116 o 0:cb9a9f314b8b a
117 117
118 118 check hidden revision are ignored (6 have hidden children 7 and 8)
119 119
120 120 $ cat > commands.txt <<EOF
121 121 > pick b346ab9a313d 6 c
122 122 > pick c13eb81022ca 8 f
123 123 > EOF
124 124 $ hg histedit 6 --commands commands.txt
125 125 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 126
127 127
128 128
129 129 Test that rewriting leaving instability behind is allowed
130 130 ---------------------------------------------------------------------
131 131
132 132 $ hg up '.^'
133 133 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
134 134 $ hg log -r 'children(.)'
135 135 9:c13eb81022ca f (no-eol)
136 136 $ cat > commands.txt <<EOF
137 137 > edit b346ab9a313d 6 c
138 138 > EOF
139 139 $ hg histedit -r '.' --commands commands.txt
140 140 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
141 141 adding c
142 abort: Make changes as needed, you may commit or record as needed now.
142 Make changes as needed, you may commit or record as needed now.
143 143 When you are finished, run hg histedit --continue to resume.
144 144 [255]
145 145 $ echo c >> c
146 146 $ hg histedit --continue
147 147 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
148 148
149 149 $ hg log -r 'unstable()'
150 150 9:c13eb81022ca f (no-eol)
151 151
152 152 stabilise
153 153
154 154 $ hg rebase -r 'unstable()' -d .
155 155
156 156 Test dropping of changeset on the top of the stack
157 157 -------------------------------------------------------
158 158
159 159 Nothing is rewritten below, the working directory parent must be change for the
160 160 dropped changeset to be hidden.
161 161
162 162 $ cd ..
163 163 $ hg clone base droplast
164 164 updating to branch default
165 165 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
166 166 $ cd droplast
167 167 $ cat > commands.txt <<EOF
168 168 > pick 40db8afa467b 10 c
169 169 > drop b449568bf7fc 11 f
170 170 > EOF
171 171 $ hg histedit -r '40db8afa467b' --commands commands.txt
172 172 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
173 173 $ hg log -G
174 174 @ 10:40db8afa467b c
175 175 |
176 176 o 0:cb9a9f314b8b a
177 177
178 178
179 179 With rewritten ancestors
180 180
181 181 $ echo e > e
182 182 $ hg add e
183 183 $ hg commit -m g
184 184 $ echo f > f
185 185 $ hg add f
186 186 $ hg commit -m h
187 187 $ cat > commands.txt <<EOF
188 188 > pick 47a8561c0449 12 g
189 189 > pick 40db8afa467b 10 c
190 190 > drop 1b3b05f35ff0 13 h
191 191 > EOF
192 192 $ hg histedit -r '40db8afa467b' --commands commands.txt
193 193 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
194 194 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
195 195 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
196 196 $ hg log -G
197 197 @ 15:ee6544123ab8 c
198 198 |
199 199 o 14:269e713e9eae g
200 200 |
201 201 o 0:cb9a9f314b8b a
202 202
203 203 $ cd ../base
204 204
205 205
206 206
207 207 Test phases support
208 208 ===========================================
209 209
210 210 Check that histedit respect immutability
211 211 -------------------------------------------
212 212
213 213 $ cat >> $HGRCPATH << EOF
214 214 > [ui]
215 215 > logtemplate= {rev}:{node|short} ({phase}) {desc|firstline}\n
216 216 > EOF
217 217
218 218 $ hg ph -pv '.^'
219 219 phase changed for 2 changesets
220 220 $ hg log -G
221 221 @ 11:b449568bf7fc (draft) f
222 222 |
223 223 o 10:40db8afa467b (public) c
224 224 |
225 225 o 0:cb9a9f314b8b (public) a
226 226
227 227 $ hg histedit -r '.~2'
228 228 abort: cannot edit immutable changeset: cb9a9f314b8b
229 229 [255]
230 230
231 231
232 232 Prepare further testing
233 233 -------------------------------------------
234 234
235 235 $ for x in g h i j k ; do
236 236 > echo $x > $x
237 237 > hg add $x
238 238 > hg ci -m $x
239 239 > done
240 240 $ hg phase --force --secret .~2
241 241 $ hg log -G
242 242 @ 16:ee118ab9fa44 (secret) k
243 243 |
244 244 o 15:3a6c53ee7f3d (secret) j
245 245 |
246 246 o 14:b605fb7503f2 (secret) i
247 247 |
248 248 o 13:7395e1ff83bd (draft) h
249 249 |
250 250 o 12:6b70183d2492 (draft) g
251 251 |
252 252 o 11:b449568bf7fc (draft) f
253 253 |
254 254 o 10:40db8afa467b (public) c
255 255 |
256 256 o 0:cb9a9f314b8b (public) a
257 257
258 258 $ cd ..
259 259
260 260 simple phase conservation
261 261 -------------------------------------------
262 262
263 263 Resulting changeset should conserve the phase of the original one whatever the
264 264 phases.new-commit option is.
265 265
266 266 New-commit as draft (default)
267 267
268 268 $ cp -r base simple-draft
269 269 $ cd simple-draft
270 270 $ cat > commands.txt <<EOF
271 271 > edit b449568bf7fc 11 f
272 272 > pick 6b70183d2492 12 g
273 273 > pick 7395e1ff83bd 13 h
274 274 > pick b605fb7503f2 14 i
275 275 > pick 3a6c53ee7f3d 15 j
276 276 > pick ee118ab9fa44 16 k
277 277 > EOF
278 278 $ hg histedit -r 'b449568bf7fc' --commands commands.txt
279 279 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
280 280 adding f
281 abort: Make changes as needed, you may commit or record as needed now.
281 Make changes as needed, you may commit or record as needed now.
282 282 When you are finished, run hg histedit --continue to resume.
283 283 [255]
284 284 $ echo f >> f
285 285 $ hg histedit --continue
286 286 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
287 287 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
288 288 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
289 289 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
290 290 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 291 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
292 292 $ hg log -G
293 293 @ 22:12e89af74238 (secret) k
294 294 |
295 295 o 21:636a8687b22e (secret) j
296 296 |
297 297 o 20:ccaf0a38653f (secret) i
298 298 |
299 299 o 19:11a89d1c2613 (draft) h
300 300 |
301 301 o 18:c1dec7ca82ea (draft) g
302 302 |
303 303 o 17:087281e68428 (draft) f
304 304 |
305 305 o 10:40db8afa467b (public) c
306 306 |
307 307 o 0:cb9a9f314b8b (public) a
308 308
309 309 $ cd ..
310 310
311 311
312 312 New-commit as draft (default)
313 313
314 314 $ cp -r base simple-secret
315 315 $ cd simple-secret
316 316 $ cat >> .hg/hgrc << EOF
317 317 > [phases]
318 318 > new-commit=secret
319 319 > EOF
320 320 $ cat > commands.txt <<EOF
321 321 > edit b449568bf7fc 11 f
322 322 > pick 6b70183d2492 12 g
323 323 > pick 7395e1ff83bd 13 h
324 324 > pick b605fb7503f2 14 i
325 325 > pick 3a6c53ee7f3d 15 j
326 326 > pick ee118ab9fa44 16 k
327 327 > EOF
328 328 $ hg histedit -r 'b449568bf7fc' --commands commands.txt
329 329 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
330 330 adding f
331 abort: Make changes as needed, you may commit or record as needed now.
331 Make changes as needed, you may commit or record as needed now.
332 332 When you are finished, run hg histedit --continue to resume.
333 333 [255]
334 334 $ echo f >> f
335 335 $ hg histedit --continue
336 336 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
337 337 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
338 338 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
339 339 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 340 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
341 341 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
342 342 $ hg log -G
343 343 @ 22:12e89af74238 (secret) k
344 344 |
345 345 o 21:636a8687b22e (secret) j
346 346 |
347 347 o 20:ccaf0a38653f (secret) i
348 348 |
349 349 o 19:11a89d1c2613 (draft) h
350 350 |
351 351 o 18:c1dec7ca82ea (draft) g
352 352 |
353 353 o 17:087281e68428 (draft) f
354 354 |
355 355 o 10:40db8afa467b (public) c
356 356 |
357 357 o 0:cb9a9f314b8b (public) a
358 358
359 359 $ cd ..
360 360
361 361
362 362 Changeset reordering
363 363 -------------------------------------------
364 364
365 365 If a secret changeset is put before a draft one, all descendant should be secret.
366 366 It seems more important to present the secret phase.
367 367
368 368 $ cp -r base reorder
369 369 $ cd reorder
370 370 $ cat > commands.txt <<EOF
371 371 > pick b449568bf7fc 11 f
372 372 > pick 3a6c53ee7f3d 15 j
373 373 > pick 6b70183d2492 12 g
374 374 > pick b605fb7503f2 14 i
375 375 > pick 7395e1ff83bd 13 h
376 376 > pick ee118ab9fa44 16 k
377 377 > EOF
378 378 $ hg histedit -r 'b449568bf7fc' --commands commands.txt
379 379 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
380 380 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
381 381 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
382 382 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
383 383 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
384 384 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
385 385 $ hg log -G
386 386 @ 21:558246857888 (secret) k
387 387 |
388 388 o 20:28bd44768535 (secret) h
389 389 |
390 390 o 19:d5395202aeb9 (secret) i
391 391 |
392 392 o 18:21edda8e341b (secret) g
393 393 |
394 394 o 17:5ab64f3a4832 (secret) j
395 395 |
396 396 o 11:b449568bf7fc (draft) f
397 397 |
398 398 o 10:40db8afa467b (public) c
399 399 |
400 400 o 0:cb9a9f314b8b (public) a
401 401
402 402 $ cd ..
403 403
404 404 Changeset folding
405 405 -------------------------------------------
406 406
407 407 Folding a secret changeset with a draft one turn the result secret (again,
408 408 better safe than sorry). Folding between same phase changeset still works
409 409
410 410 Note that there is a few reordering in this series for more extensive test
411 411
412 412 $ cp -r base folding
413 413 $ cd folding
414 414 $ cat >> .hg/hgrc << EOF
415 415 > [phases]
416 416 > new-commit=secret
417 417 > EOF
418 418 $ cat > commands.txt <<EOF
419 419 > pick 7395e1ff83bd 13 h
420 420 > fold b449568bf7fc 11 f
421 421 > pick 6b70183d2492 12 g
422 422 > fold 3a6c53ee7f3d 15 j
423 423 > pick b605fb7503f2 14 i
424 424 > fold ee118ab9fa44 16 k
425 425 > EOF
426 426 $ hg histedit -r 'b449568bf7fc' --commands commands.txt
427 427 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
428 428 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
429 429 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
430 430 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
431 431 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
432 432 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
433 433 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
434 434 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
435 435 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
436 436 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
437 437 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
438 438 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
439 439 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
440 440 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/58019c66f35f-backup.hg (glob)
441 441 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/83d1858e070b-backup.hg (glob)
442 442 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/859969f5ed7e-backup.hg (glob)
443 443 $ hg log -G
444 444 @ 19:f9daec13fb98 (secret) i
445 445 |
446 446 o 18:49807617f46a (secret) g
447 447 |
448 448 o 17:050280826e04 (draft) h
449 449 |
450 450 o 10:40db8afa467b (public) c
451 451 |
452 452 o 0:cb9a9f314b8b (public) a
453 453
454 454 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now