--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext/histedit.py Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,564 @@
+# histedit.py - interactive history editing for mercurial
+#
+# Copyright 2009 Augie Fackler <raf@durin42.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+"""Interactive history editing.
+
+Inspired by git rebase --interactive.
+"""
+from inspect import getargspec
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+import tempfile
+import os
+
+from mercurial import bookmarks
+from mercurial import cmdutil
+from mercurial import discovery
+from mercurial import error
+from mercurial import hg
+from mercurial import node
+from mercurial import patch
+from mercurial import repair
+from mercurial import scmutil
+from mercurial import url
+from mercurial import util
+from mercurial.i18n import _
+
+
+editcomment = """
+
+# Edit history between %s and %s
+#
+# Commands:
+# p, pick = use commit
+# e, edit = use commit, but stop for amending
+# f, fold = use commit, but fold into previous commit (combines N and N-1)
+# d, drop = remove commit from history
+# m, mess = edit message without changing commit content
+#
+"""
+
+def between(repo, old, new, keep):
+ revs = [old, ]
+ current = old
+ while current != new:
+ ctx = repo[current]
+ if not keep and len(ctx.children()) > 1:
+ raise util.Abort(_('cannot edit history that would orphan nodes'))
+ if len(ctx.parents()) != 1 and ctx.parents()[1] != node.nullid:
+ raise util.Abort(_("can't edit history with merges"))
+ if not ctx.children():
+ current = new
+ else:
+ current = ctx.children()[0].node()
+ revs.append(current)
+ if len(repo[current].children()) and not keep:
+ raise util.Abort(_('cannot edit history that would orphan nodes'))
+ return revs
+
+
+def pick(ui, repo, ctx, ha, opts):
+ oldctx = repo[ha]
+ if oldctx.parents()[0] == ctx:
+ ui.debug('node %s unchanged\n' % ha)
+ return oldctx, [], [], []
+ hg.update(repo, ctx.node())
+ fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
+ fp = os.fdopen(fd, 'w')
+ diffopts = patch.diffopts(ui, opts)
+ diffopts.git = True
+ diffopts.ignorews = False
+ diffopts.ignorewsamount = False
+ diffopts.ignoreblanklines = False
+ gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
+ for chunk in gen:
+ fp.write(chunk)
+ fp.close()
+ try:
+ files = set()
+ try:
+ patch.patch(ui, repo, patchfile, files=files, eolmode=None)
+ if not files:
+ ui.warn(_('%s: empty changeset')
+ % node.hex(ha))
+ return ctx, [], [], []
+ finally:
+ os.unlink(patchfile)
+ except Exception, inst:
+ raise util.Abort(_('Fix up the change and run '
+ 'hg histedit --continue'))
+ n = repo.commit(text=oldctx.description(), user=oldctx.user(), date=oldctx.date(),
+ extra=oldctx.extra())
+ return repo[n], [n, ], [oldctx.node(), ], []
+
+
+def edit(ui, repo, ctx, ha, opts):
+ oldctx = repo[ha]
+ hg.update(repo, ctx.node())
+ fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
+ fp = os.fdopen(fd, 'w')
+ diffopts = patch.diffopts(ui, opts)
+ diffopts.git = True
+ diffopts.ignorews = False
+ diffopts.ignorewsamount = False
+ diffopts.ignoreblanklines = False
+ gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
+ for chunk in gen:
+ fp.write(chunk)
+ fp.close()
+ try:
+ files = set()
+ try:
+ patch.patch(ui, repo, patchfile, files=files, eolmode=None)
+ finally:
+ os.unlink(patchfile)
+ except Exception, inst:
+ pass
+ raise util.Abort(_('Make changes as needed, you may commit or record as '
+ 'needed now.\nWhen you are finished, run hg'
+ ' histedit --continue to resume.'))
+
+def fold(ui, repo, ctx, ha, opts):
+ oldctx = repo[ha]
+ hg.update(repo, ctx.node())
+ fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
+ fp = os.fdopen(fd, 'w')
+ diffopts = patch.diffopts(ui, opts)
+ diffopts.git = True
+ diffopts.ignorews = False
+ diffopts.ignorewsamount = False
+ diffopts.ignoreblanklines = False
+ gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
+ for chunk in gen:
+ fp.write(chunk)
+ fp.close()
+ try:
+ files = set()
+ try:
+ patch.patch(ui, repo, patchfile, files=files, eolmode=None)
+ if not files:
+ ui.warn(_('%s: empty changeset')
+ % node.hex(ha))
+ return ctx, [], [], []
+ finally:
+ os.unlink(patchfile)
+ except Exception, inst:
+ raise util.Abort(_('Fix up the change and run '
+ 'hg histedit --continue'))
+ n = repo.commit(text='fold-temp-revision %s' % ha, user=oldctx.user(), date=oldctx.date(),
+ extra=oldctx.extra())
+ return finishfold(ui, repo, ctx, oldctx, n, opts, [])
+
+def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges):
+ parent = ctx.parents()[0].node()
+ hg.update(repo, parent)
+ fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
+ fp = os.fdopen(fd, 'w')
+ diffopts = patch.diffopts(ui, opts)
+ diffopts.git = True
+ diffopts.ignorews = False
+ diffopts.ignorewsamount = False
+ diffopts.ignoreblanklines = False
+ gen = patch.diff(repo, parent, newnode, opts=diffopts)
+ for chunk in gen:
+ fp.write(chunk)
+ fp.close()
+ files = set()
+ try:
+ patch.patch(ui, repo, patchfile, files=files, eolmode=None)
+ finally:
+ os.unlink(patchfile)
+ newmessage = '\n***\n'.join(
+ [ctx.description(), ] +
+ [repo[r].description() for r in internalchanges] +
+ [oldctx.description(), ])
+ # If the changesets are from the same author, keep it.
+ if ctx.user() == oldctx.user():
+ username = ctx.user()
+ else:
+ username = ui.username()
+ newmessage = ui.edit(newmessage, username)
+ n = repo.commit(text=newmessage, user=username, date=max(ctx.date(), oldctx.date()),
+ extra=oldctx.extra())
+ return repo[n], [n, ], [oldctx.node(), ctx.node() ], [newnode, ]
+
+def drop(ui, repo, ctx, ha, opts):
+ return ctx, [], [repo[ha].node(), ], []
+
+
+def message(ui, repo, ctx, ha, opts):
+ oldctx = repo[ha]
+ hg.update(repo, ctx.node())
+ fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
+ fp = os.fdopen(fd, 'w')
+ diffopts = patch.diffopts(ui, opts)
+ diffopts.git = True
+ diffopts.ignorews = False
+ diffopts.ignorewsamount = False
+ diffopts.ignoreblanklines = False
+ gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
+ for chunk in gen:
+ fp.write(chunk)
+ fp.close()
+ try:
+ files = set()
+ try:
+ patch.patch(ui, repo, patchfile, files=files, eolmode=None)
+ finally:
+ os.unlink(patchfile)
+ except Exception, inst:
+ raise util.Abort(_('Fix up the change and run '
+ 'hg histedit --continue'))
+ message = oldctx.description()
+ message = ui.edit(message, ui.username())
+ new = repo.commit(text=message, user=oldctx.user(), date=oldctx.date(),
+ extra=oldctx.extra())
+ newctx = repo[new]
+ if oldctx.node() != newctx.node():
+ return newctx, [new], [oldctx.node()], []
+ # We didn't make an edit, so just indicate no replaced nodes
+ return newctx, [new], [], []
+
+
+def makedesc(c):
+ summary = ''
+ if c.description():
+ summary = c.description().splitlines()[0]
+ line = 'pick %s %d %s' % (c.hex()[:12], c.rev(), summary)
+ return line[:80] # trim to 80 chars so it's not stupidly wide in my editor
+
+actiontable = {'p': pick,
+ 'pick': pick,
+ 'e': edit,
+ 'edit': edit,
+ 'f': fold,
+ 'fold': fold,
+ 'd': drop,
+ 'drop': drop,
+ 'm': message,
+ 'mess': message,
+ }
+def histedit(ui, repo, *parent, **opts):
+ """hg histedit <parent>
+ """
+ # TODO only abort if we try and histedit mq patches, not just
+ # blanket if mq patches are applied somewhere
+ mq = getattr(repo, 'mq', None)
+ if mq and mq.applied:
+ raise util.Abort(_('source has mq patches applied'))
+
+ parent = list(parent) + opts.get('rev', [])
+ if opts.get('outgoing'):
+ if len(parent) > 1:
+ raise util.Abort(_('only one repo argument allowed with --outgoing'))
+ elif parent:
+ parent = parent[0]
+
+ dest = ui.expandpath(parent or 'default-push', parent or 'default')
+ dest, revs = hg.parseurl(dest, None)[:2]
+ ui.status(_('comparing with %s\n') % util.hidepassword(dest))
+
+ revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
+ other = hg.repository(hg.remoteui(repo, opts), dest)
+
+ if revs:
+ revs = [repo.lookup(rev) for rev in revs]
+
+ parent = discovery.findcommonoutgoing(
+ repo, other, [], force=opts.get('force')).missing[0:1]
+ else:
+ if opts.get('force'):
+ raise util.Abort(_('--force only allowed with --outgoing'))
+
+ if opts.get('continue', False):
+ if len(parent) != 0:
+ raise util.Abort(_('no arguments allowed with --continue'))
+ (parentctxnode, created, replaced,
+ tmpnodes, existing, rules, keep, tip, replacemap ) = readstate(repo)
+ currentparent, wantnull = repo.dirstate.parents()
+ parentctx = repo[parentctxnode]
+ # discover any nodes the user has added in the interim
+ newchildren = [c for c in parentctx.children()
+ if c.node() not in existing]
+ action, currentnode = rules.pop(0)
+ while newchildren:
+ if action in ['f', 'fold', ]:
+ tmpnodes.extend([n.node() for n in newchildren])
+ else:
+ created.extend([n.node() for n in newchildren])
+ newchildren = filter(lambda x: x.node() not in existing,
+ reduce(lambda x, y: x + y,
+ map(lambda r: r.children(),
+ newchildren)))
+ m, a, r, d = repo.status()[:4]
+ oldctx = repo[currentnode]
+ message = oldctx.description()
+ if action in ('e', 'edit', 'm', 'mess'):
+ message = ui.edit(message, ui.username())
+ elif action in ('f', 'fold', ):
+ message = 'fold-temp-revision %s' % currentnode
+ new = None
+ if m or a or r or d:
+ new = repo.commit(text=message, user=oldctx.user(), date=oldctx.date(),
+ extra=oldctx.extra())
+
+ if action in ('f', 'fold'):
+ if new:
+ tmpnodes.append(new)
+ else:
+ new = newchildren[-1]
+ (parentctx, created_,
+ replaced_, tmpnodes_, ) = finishfold(ui, repo,
+ parentctx, oldctx, new,
+ opts, newchildren)
+ replaced.extend(replaced_)
+ created.extend(created_)
+ tmpnodes.extend(tmpnodes_)
+ elif action not in ('d', 'drop'):
+ if new != oldctx.node():
+ replaced.append(oldctx.node())
+ if new:
+ if new != oldctx.node():
+ created.append(new)
+ parentctx = repo[new]
+
+ elif opts.get('abort', False):
+ if len(parent) != 0:
+ raise util.Abort(_('no arguments allowed with --abort'))
+ (parentctxnode, created, replaced, tmpnodes,
+ existing, rules, keep, tip, replacemap) = readstate(repo)
+ ui.debug('restore wc to old tip %s\n' % node.hex(tip))
+ hg.clean(repo, tip)
+ ui.debug('should strip created nodes %s\n' %
+ ', '.join([node.hex(n)[:12] for n in created]))
+ ui.debug('should strip temp nodes %s\n' %
+ ', '.join([node.hex(n)[:12] for n in tmpnodes]))
+ for nodes in (created, tmpnodes, ):
+ for n in reversed(nodes):
+ try:
+ repair.strip(ui, repo, n)
+ except error.LookupError:
+ pass
+ os.unlink(os.path.join(repo.path, 'histedit-state'))
+ return
+ else:
+ cmdutil.bailifchanged(repo)
+ if os.path.exists(os.path.join(repo.path, 'histedit-state')):
+ raise util.Abort(_('history edit already in progress, try '
+ '--continue or --abort'))
+
+ tip, empty = repo.dirstate.parents()
+
+
+ if len(parent) != 1:
+ raise util.Abort(_('histedit requires exactly one parent revision'))
+ parent = scmutil.revsingle(repo, parent[0]).node()
+
+ keep = opts.get('keep', False)
+ revs = between(repo, parent, tip, keep)
+
+ ctxs = [repo[r] for r in revs]
+ existing = [r.node() for r in ctxs]
+ rules = opts.get('commands', '')
+ if not rules:
+ rules = '\n'.join([makedesc(c) for c in ctxs])
+ rules += editcomment % (node.hex(parent)[:12], node.hex(tip)[:12], )
+ rules = ui.edit(rules, ui.username())
+ # Save edit rules in .hg/histedit-last-edit.txt in case
+ # the user needs to ask for help after something
+ # surprising happens.
+ f = open(repo.join('histedit-last-edit.txt'), 'w')
+ f.write(rules)
+ f.close()
+ else:
+ f = open(rules)
+ rules = f.read()
+ f.close()
+ rules = [l for l in (r.strip() for r in rules.splitlines())
+ if l and not l[0] == '#']
+ rules = verifyrules(rules, repo, ctxs)
+
+ parentctx = repo[parent].parents()[0]
+ keep = opts.get('keep', False)
+ replaced = []
+ replacemap = {}
+ tmpnodes = []
+ created = []
+
+
+ while rules:
+ writestate(repo, parentctx.node(), created, replaced, tmpnodes, existing,
+ rules, keep, tip, replacemap)
+ action, ha = rules.pop(0)
+ (parentctx, created_,
+ replaced_, tmpnodes_, ) = actiontable[action](ui, repo,
+ parentctx, ha,
+ opts)
+
+ hexshort = lambda x: node.hex(x)[:12]
+
+ if replaced_:
+ clen, rlen = len(created_), len(replaced_)
+ if clen == rlen == 1:
+ ui.debug('histedit: exact replacement of %s with %s\n' % (
+ hexshort(replaced_[0]), hexshort(created_[0])))
+
+ replacemap[replaced_[0]] = created_[0]
+ elif clen > rlen:
+ assert rlen == 1, ('unexpected replacement of '
+ '%d changes with %d changes' % (rlen, clen))
+ # made more changesets than we're replacing
+ # TODO synthesize patch names for created patches
+ replacemap[replaced_[0]] = created_[-1]
+ ui.debug('histedit: created many, assuming %s replaced by %s' % (
+ hexshort(replaced_[0]), hexshort(created_[-1])))
+ elif rlen > clen:
+ if not created_:
+ # This must be a drop. Try and put our metadata on
+ # the parent change.
+ assert rlen == 1
+ r = replaced_[0]
+ ui.debug('histedit: %s seems replaced with nothing, '
+ 'finding a parent\n' % (hexshort(r)))
+ pctx = repo[r].parents()[0]
+ if pctx.node() in replacemap:
+ ui.debug('histedit: parent is already replaced\n')
+ replacemap[r] = replacemap[pctx.node()]
+ else:
+ replacemap[r] = pctx.node()
+ ui.debug('histedit: %s best replaced by %s\n' % (
+ hexshort(r), hexshort(replacemap[r])))
+ else:
+ assert len(created_) == 1
+ for r in replaced_:
+ ui.debug('histedit: %s replaced by %s\n' % (
+ hexshort(r), hexshort(created_[0])))
+ replacemap[r] = created_[0]
+ else:
+ assert False, (
+ 'Unhandled case in replacement mapping! '
+ 'replacing %d changes with %d changes' % (rlen, clen))
+ created.extend(created_)
+ replaced.extend(replaced_)
+ tmpnodes.extend(tmpnodes_)
+
+ hg.update(repo, parentctx.node())
+
+ if not keep:
+ if replacemap:
+ ui.note('histedit: Should update metadata for the following '
+ 'changes:\n')
+
+ def copybms(old, new):
+ if old in tmpnodes or old in created:
+ # can't have any metadata we'd want to update
+ return
+ while new in replacemap:
+ new = replacemap[new]
+ ui.note('histedit: %s to %s\n' % (hexshort(old), hexshort(new)))
+ octx = repo[old]
+ marks = octx.bookmarks()
+ if marks:
+ ui.note('histedit: moving bookmarks %s\n' %
+ ', '.join(marks))
+ for mark in marks:
+ repo._bookmarks[mark] = new
+ bookmarks.write(repo)
+
+ # We assume that bookmarks on the tip should remain
+ # tipmost, but bookmarks on non-tip changesets should go
+ # to their most reasonable successor. As a result, find
+ # the old tip and new tip and copy those bookmarks first,
+ # then do the rest of the bookmark copies.
+ oldtip = sorted(replacemap.keys(), key=repo.changelog.rev)[-1]
+ newtip = sorted(replacemap.values(), key=repo.changelog.rev)[-1]
+ copybms(oldtip, newtip)
+
+ for old, new in replacemap.iteritems():
+ copybms(old, new)
+ # TODO update mq state
+
+ ui.debug('should strip replaced nodes %s\n' %
+ ', '.join([node.hex(n)[:12] for n in replaced]))
+ for n in sorted(replaced, key=lambda x: repo[x].rev()):
+ try:
+ repair.strip(ui, repo, n)
+ except error.LookupError:
+ pass
+
+ ui.debug('should strip temp nodes %s\n' %
+ ', '.join([node.hex(n)[:12] for n in tmpnodes]))
+ for n in reversed(tmpnodes):
+ try:
+ repair.strip(ui, repo, n)
+ except error.LookupError:
+ pass
+ os.unlink(os.path.join(repo.path, 'histedit-state'))
+ if os.path.exists(repo.sjoin('undo')):
+ os.unlink(repo.sjoin('undo'))
+
+
+def writestate(repo, parentctxnode, created, replaced,
+ tmpnodes, existing, rules, keep, oldtip, replacemap):
+ fp = open(os.path.join(repo.path, 'histedit-state'), 'w')
+ pickle.dump((parentctxnode, created, replaced,
+ tmpnodes, existing, rules, keep, oldtip, replacemap),
+ fp)
+ fp.close()
+
+def readstate(repo):
+ """Returns a tuple of (parentnode, created, replaced, tmp, existing, rules,
+ keep, oldtip, replacemap ).
+ """
+ fp = open(os.path.join(repo.path, 'histedit-state'))
+ return pickle.load(fp)
+
+
+def verifyrules(rules, repo, ctxs):
+ """Verify that there exists exactly one edit rule per given changeset.
+
+ Will abort if there are to many or too few rules, a malformed rule,
+ or a rule on a changeset outside of the user-given range.
+ """
+ parsed = []
+ first = True
+ if len(rules) != len(ctxs):
+ raise util.Abort(_('must specify a rule for each changeset once'))
+ for r in rules:
+ if ' ' not in r:
+ raise util.Abort(_('malformed line "%s"') % r)
+ action, rest = r.split(' ', 1)
+ if ' ' in rest.strip():
+ ha, rest = rest.split(' ', 1)
+ else:
+ ha = r.strip()
+ try:
+ if repo[ha] not in ctxs:
+ raise util.Abort(_('may not use changesets other than the ones listed'))
+ except error.RepoError:
+ raise util.Abort(_('unknown changeset %s listed') % ha)
+ if action not in actiontable:
+ raise util.Abort(_('unknown action "%s"') % action)
+ parsed.append([action, ha])
+ return parsed
+
+
+cmdtable = {
+ "histedit":
+ (histedit,
+ [('', 'commands', '', _('Read history edits from the specified file.')),
+ ('c', 'continue', False, _('continue an edit already in progress')),
+ ('k', 'keep', False, _("don't strip old nodes after edit is complete")),
+ ('', 'abort', False, _('abort an edit in progress')),
+ ('o', 'outgoing', False, _('changesets not found in destination')),
+ ('f', 'force', False, _('force outgoing even for unrelated repositories')),
+ ('r', 'rev', [], _('first revision to be edited')),
+ ],
+ __doc__,
+ ),
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/histedit-helpers.sh Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+fixbundle() {
+ grep -v 'saving bundle' | grep -v 'saved backup' | \
+ grep -v added | grep -v adding | \
+ grep -v "unable to find 'e' for patching" | \
+ grep -v "e: No such file or directory"
+}
Binary file tests/missing-comment.hg has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-bookmark-motion.t Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,190 @@
+ $ . "$TESTDIR/histedit-helpers.sh"
+
+ $ cat >> $HGRCPATH <<EOF
+ > [extensions]
+ > graphlog=
+ > histedit=
+ > EOF
+
+ $ hg init r
+ $ cd r
+See if bookmarks are in core. If not, then we don't support bookmark
+motion on this version of hg.
+ $ hg bookmarks || exit 80
+ no bookmarks set
+ $ for x in a b c d e f ; do
+ > echo $x > $x
+ > hg add $x
+ > hg ci -m $x
+ > done
+
+ $ hg book -r 1 will-move-backwards
+ $ hg book -r 2 two
+ $ hg book -r 2 also-two
+ $ hg book -r 3 three
+ $ hg book -r 4 four
+ $ hg book -r tip five
+ $ hg log --graph
+ @ changeset: 5:652413bf663e
+ | bookmark: five
+ | tag: tip
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: f
+ |
+ o changeset: 4:e860deea161a
+ | bookmark: four
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: e
+ |
+ o changeset: 3:055a42cdd887
+ | bookmark: three
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: d
+ |
+ o changeset: 2:177f92b77385
+ | bookmark: also-two
+ | bookmark: two
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: c
+ |
+ o changeset: 1:d2ae7f538514
+ | bookmark: will-move-backwards
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: b
+ |
+ o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+ $ HGEDITOR=cat hg histedit 1
+ pick d2ae7f538514 1 b
+ pick 177f92b77385 2 c
+ pick 055a42cdd887 3 d
+ pick e860deea161a 4 e
+ pick 652413bf663e 5 f
+
+ # Edit history between d2ae7f538514 and 652413bf663e
+ #
+ # Commands:
+ # p, pick = use commit
+ # e, edit = use commit, but stop for amending
+ # f, fold = use commit, but fold into previous commit (combines N and N-1)
+ # d, drop = remove commit from history
+ # m, mess = edit message without changing commit content
+ #
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cat >> commands.txt <<EOF
+ > pick 177f92b77385 2 c
+ > drop d2ae7f538514 1 b
+ > pick 055a42cdd887 3 d
+ > fold e860deea161a 4 e
+ > pick 652413bf663e 5 f
+ > EOF
+ $ hg histedit 1 --commands commands.txt --verbose | grep histedit
+ histedit: Should update metadata for the following changes:
+ histedit: 055a42cdd887 to ae467701c500
+ histedit: moving bookmarks three
+ histedit: 652413bf663e to 0efacef7cb48
+ histedit: moving bookmarks five
+ histedit: d2ae7f538514 to cb9a9f314b8b
+ histedit: moving bookmarks will-move-backwards
+ histedit: e860deea161a to ae467701c500
+ histedit: moving bookmarks four
+ histedit: 177f92b77385 to d36c0562f908
+ histedit: moving bookmarks also-two, two
+ saved backup bundle to $TESTTMP/r/.hg/strip-backup/d2ae7f538514-backup.hg
+ saved backup bundle to $TESTTMP/r/.hg/strip-backup/34a9919932c1-backup.hg
+ $ hg log --graph
+ @ changeset: 3:0efacef7cb48
+ | bookmark: five
+ | tag: tip
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: f
+ |
+ o changeset: 2:ae467701c500
+ | bookmark: four
+ | bookmark: three
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: d
+ |
+ o changeset: 1:d36c0562f908
+ | bookmark: also-two
+ | bookmark: two
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: c
+ |
+ o changeset: 0:cb9a9f314b8b
+ bookmark: will-move-backwards
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+ $ HGEDITOR=cat hg histedit 1
+ pick d36c0562f908 1 c
+ pick ae467701c500 2 d
+ pick 0efacef7cb48 3 f
+
+ # Edit history between d36c0562f908 and 0efacef7cb48
+ #
+ # Commands:
+ # p, pick = use commit
+ # e, edit = use commit, but stop for amending
+ # f, fold = use commit, but fold into previous commit (combines N and N-1)
+ # d, drop = remove commit from history
+ # m, mess = edit message without changing commit content
+ #
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cat > commands.txt << EOF
+ > pick d36c0562f908 1 c
+ > pick 0efacef7cb48 3 f
+ > pick ae467701c500 2 d
+ > EOF
+ $ hg histedit 1 --commands commands.txt --verbose | grep histedit
+ histedit: Should update metadata for the following changes:
+ histedit: 0efacef7cb48 to 1be9c35b4cb2
+ histedit: moving bookmarks five
+ histedit: ae467701c500 to 1be9c35b4cb2
+ histedit: moving bookmarks four, three
+ histedit: 0efacef7cb48 to 7c044e3e33a9
+ saved backup bundle to $TESTTMP/r/.hg/strip-backup/ae467701c500-backup.hg
+
+We expect 'five' to stay at tip, since the tipmost bookmark is most
+likely the useful signal.
+
+ $ hg log --graph
+ @ changeset: 3:1be9c35b4cb2
+ | bookmark: five
+ | bookmark: four
+ | bookmark: three
+ | tag: tip
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: d
+ |
+ o changeset: 2:7c044e3e33a9
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: f
+ |
+ o changeset: 1:d36c0562f908
+ | bookmark: also-two
+ | bookmark: two
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: c
+ |
+ o changeset: 0:cb9a9f314b8b
+ bookmark: will-move-backwards
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-commute Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,97 @@
+#!/bin/sh
+
+. "$TESTDIR/histedit-helpers.sh"
+
+cat >> $HGRCPATH <<EOF
+[extensions]
+graphlog=
+histedit=
+EOF
+
+EDITED=`pwd`/editedhistory
+cat > $EDITED <<EOF
+pick 177f92b77385 c
+pick e860deea161a e
+pick 652413bf663e f
+pick 055a42cdd887 d
+EOF
+initrepo ()
+{
+ hg init r
+ cd r
+ for x in a b c d e f ; do
+ echo $x > $x
+ hg add $x
+ hg ci -m $x
+ done
+}
+
+initrepo
+
+echo % log before edit
+hg log --graph
+
+echo % show the edit commands offered
+HGEDITOR=cat hg histedit 177f92b77385
+
+echo % edit the history
+HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
+
+echo % rules should end up in .hg/histedit-last-edit.txt:
+cat .hg/histedit-last-edit.txt
+echo '**** end of rules file ****'
+
+echo % log after edit
+hg log --graph
+
+echo % put things back
+
+cat > $EDITED <<EOF
+pick 177f92b77385 c
+pick 853c68da763f d
+pick b069cc29fb22 e
+pick 26f6a030ae82 f
+EOF
+HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
+
+hg log --graph
+
+
+echo % slightly different this time
+
+cat > $EDITED <<EOF
+pick 055a42cdd887 d
+pick 652413bf663e f
+pick e860deea161a e
+pick 177f92b77385 c
+EOF
+HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
+hg log --graph
+
+
+echo % keep prevents stripping dead revs
+cat > $EDITED <<EOF
+pick bfe4a5a76b37 d
+pick c4f52e213402 f
+pick 99a62755c625 c
+pick 7c6fdd608667 e
+EOF
+HGEDITOR="cat $EDITED > " hg histedit bfe4a5a76b37 --keep 2>&1 | fixbundle
+hg log --graph
+
+echo '% try with --rev'
+cat > $EDITED <<EOF
+pick 7c6fdd608667 e
+pick 99a62755c625 c
+EOF
+hg histedit --commands "$EDITED" --rev -2 2>&1 | fixbundle
+hg log --graph
+
+echo % should also work if a commit message is missing
+BUNDLE="$TESTDIR/missing-comment.hg"
+hg init missing
+cd missing
+hg unbundle $BUNDLE
+hg co tip
+hg log --graph
+hg histedit 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-commute.out Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,277 @@
+% log before edit
+@ changeset: 5:652413bf663e
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:e860deea161a
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% show the edit commands offered
+pick 177f92b77385 2 c
+pick 055a42cdd887 3 d
+pick e860deea161a 4 e
+pick 652413bf663e 5 f
+
+# Edit history between 177f92b77385 and 652413bf663e
+#
+# Commands:
+# p, pick = use commit
+# e, edit = use commit, but stop for amending
+# f, fold = use commit, but fold into previous commit (combines N and N-1)
+# d, drop = remove commit from history
+# m, mess = edit message without changing commit content
+#
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% edit the history
+0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% rules should end up in .hg/histedit-last-edit.txt:
+pick 177f92b77385 c
+pick e860deea161a e
+pick 652413bf663e f
+pick 055a42cdd887 d
+**** end of rules file ****
+% log after edit
+@ changeset: 5:853c68da763f
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 4:26f6a030ae82
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 3:b069cc29fb22
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% put things back
+0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@ changeset: 5:652413bf663e
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:e860deea161a
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% slightly different this time
+0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@ changeset: 5:99a62755c625
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 4:7c6fdd608667
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:c4f52e213402
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 2:bfe4a5a76b37
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% keep prevents stripping dead revs
+0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@ changeset: 7:99e266581538
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 6:5ad36efb0653
+| parent: 3:c4f52e213402
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+| o changeset: 5:99a62755c625
+| | user: test
+| | date: Thu Jan 01 00:00:00 1970 +0000
+| | summary: c
+| |
+| o changeset: 4:7c6fdd608667
+|/ user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:c4f52e213402
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 2:bfe4a5a76b37
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% try with --rev
+abort: may not use changesets other than the ones listed
+@ changeset: 7:99e266581538
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 6:5ad36efb0653
+| parent: 3:c4f52e213402
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+| o changeset: 5:99a62755c625
+| | user: test
+| | date: Thu Jan 01 00:00:00 1970 +0000
+| | summary: c
+| |
+| o changeset: 4:7c6fdd608667
+|/ user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:c4f52e213402
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 2:bfe4a5a76b37
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% should also work if a commit message is missing
+adding changesets
+adding manifests
+adding file changes
+added 3 changesets with 3 changes to 1 files
+(run 'hg update' to get a working copy)
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@ changeset: 2:bd22688093b3
+| tag: tip
+| user: Robert Altman <robert.altman@telventDTN.com>
+| date: Mon Nov 28 16:40:04 2011 +0000
+| summary: Update file.
+|
+o changeset: 1:3b3e956f9171
+| user: Robert Altman <robert.altman@telventDTN.com>
+| date: Mon Nov 28 16:37:57 2011 +0000
+|
+o changeset: 0:141947992243
+ user: Robert Altman <robert.altman@telventDTN.com>
+ date: Mon Nov 28 16:35:28 2011 +0000
+ summary: Checked in text file
+
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-drop Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+. "$TESTDIR/histedit-helpers.sh"
+
+cat >> $HGRCPATH <<EOF
+[extensions]
+graphlog=
+histedit=
+EOF
+
+EDITED=`pwd`/editedhistory
+cat > $EDITED <<EOF
+drop 177f92b77385 c
+pick e860deea161a e
+pick 652413bf663e f
+pick 055a42cdd887 d
+EOF
+initrepo ()
+{
+ hg init r
+ cd r
+ for x in a b c d e f ; do
+ echo $x > $x
+ hg add $x
+ hg ci -m $x
+ done
+}
+
+initrepo
+
+echo % log before edit
+hg log --graph
+
+echo % edit the history
+HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
+
+echo % log after edit
+hg log --graph
+
+echo % manifest after edit
+hg manifest
+
+echo % EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-drop.out Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,71 @@
+% log before edit
+@ changeset: 5:652413bf663e
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:e860deea161a
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% edit the history
+0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% log after edit
+@ changeset: 4:708943196e52
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 3:75cbdffecadb
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 2:493dc0964412
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% manifest after edit
+a
+b
+d
+e
+f
+% EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-edit Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+. "$TESTDIR/histedit-helpers.sh"
+
+cat >> $HGRCPATH <<EOF
+[extensions]
+graphlog=
+histedit=
+EOF
+
+EDITED=`pwd`/editedhistory
+cat > $EDITED <<EOF
+pick 177f92b77385 c
+pick 055a42cdd887 d
+edit e860deea161a e
+pick 652413bf663e f
+EOF
+initrepo ()
+{
+ hg init r
+ cd r
+ for x in a b c d e f ; do
+ echo $x > $x
+ hg add $x
+ hg ci -m $x
+ done
+}
+
+initrepo
+
+echo % log before edit
+hg log --graph
+
+echo % edit the history
+HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
+
+echo % edit the revision
+echo a > e
+HGEDITOR='echo "foobaz" > ' hg histedit --continue 2>&1 | fixbundle
+
+hg log --graph
+
+echo '% contents of e:'
+hg cat e
+
+cat > $EDITED <<EOF
+edit c38516e9ed62 f
+EOF
+HGEDITOR="cat $EDITED > " hg histedit tip 2>&1 | fixbundle
+hg status
+HGEDITOR='true' hg histedit --continue
+hg status
+
+echo % log after edit
+hg log --limit 1
+
+echo "% say we'll change the message, but don't."
+cat > ../edit.sh <<EOF
+#!/bin/sh
+cat \$1 | sed s/pick/mess/ > tmp
+mv tmp \$1
+EOF
+chmod +x ../edit.sh
+HGEDITOR="../edit.sh" hg histedit tip 2>&1 | fixbundle
+hg status
+hg log --limit 1
+
+echo % modify the message
+cat > $EDITED <<EOF
+mess c38516e9ed62 f
+EOF
+HGEDITOR="cat $EDITED > " hg histedit tip 2>&1 | fixbundle
+hg status
+hg log --limit 1
+
+echo % rollback should not work after a histedit
+hg rollback
+
+echo % EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-edit.out Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,105 @@
+% log before edit
+@ changeset: 5:652413bf663e
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:e860deea161a
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% edit the history
+0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+abort: Make changes as needed, you may commit or record as needed now.
+When you are finished, run hg histedit --continue to resume.
+% edit the revision
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@ changeset: 5:c38516e9ed62
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:1da62d13177d
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: foobaz
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% contents of e:
+a
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+abort: Make changes as needed, you may commit or record as needed now.
+When you are finished, run hg histedit --continue to resume.
+A f
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% log after edit
+changeset: 5:c38516e9ed62
+tag: tip
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: f
+
+% say we'll change the message, but don't.
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+changeset: 5:c38516e9ed62
+tag: tip
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: f
+
+% modify the message
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+changeset: 5:4d6a10bcf3e3
+tag: tip
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: mess c38516e9ed62 f
+
+% rollback should not work after a histedit
+no rollback information available
+% EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-fold Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+. "$TESTDIR/histedit-helpers.sh"
+
+cat >> $HGRCPATH <<EOF
+[extensions]
+graphlog=
+histedit=
+EOF
+
+EDITED=`pwd`/editedhistory
+cat > $EDITED <<EOF
+pick e860deea161a e
+pick 652413bf663e f
+fold 177f92b77385 c
+pick 055a42cdd887 d
+EOF
+initrepo ()
+{
+ hg init r
+ cd r
+ for x in a b c d e f ; do
+ echo $x > $x
+ hg add $x
+ hg ci -m $x
+ done
+}
+
+initrepo
+
+echo % log before edit
+hg log --graph
+
+echo % edit the history
+HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
+
+echo % log after edit
+hg log --graph
+
+echo % post-fold manifest
+hg manifest
+
+echo % EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-fold-non-commute Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+. "$TESTDIR/histedit-helpers.sh"
+
+cat >> $HGRCPATH <<EOF
+[extensions]
+graphlog=
+histedit=
+EOF
+
+EDITED=`pwd`/editedhistory
+cat > $EDITED <<EOF
+pick 177f92b77385 c
+pick 055a42cdd887 d
+fold bfa474341cc9 does not commute with e
+pick e860deea161a e
+pick 652413bf663e f
+EOF
+initrepo ()
+{
+ hg init r
+ cd r
+ for x in a b c d e f ; do
+ echo $x > $x
+ hg add $x
+ hg ci -m $x
+ done
+ echo a >> e
+ hg ci -m 'does not commute with e'
+}
+
+initrepo
+
+echo % log before edit
+hg log --graph
+
+echo % edit the history
+HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
+
+echo % fix up
+echo a > e
+hg add e
+cat > cat.py <<EOF
+import sys
+print open(sys.argv[1]).read()
+print
+print
+EOF
+HGEDITOR="python cat.py" hg histedit --continue 2>&1 | fixbundle | grep -v '2 files removed'
+
+echo
+echo % just continue this time
+hg histedit --continue 2>&1 | fixbundle
+
+
+echo % log after edit
+hg log --graph
+
+echo % contents of e
+hg cat e
+
+echo % manifest
+hg manifest
+
+echo % EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-fold-non-commute.out Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,92 @@
+% log before edit
+@ changeset: 6:bfa474341cc9
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: does not commute with e
+|
+o changeset: 5:652413bf663e
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:e860deea161a
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% edit the history
+0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+1 out of 1 hunks FAILED -- saving rejects to file e.rej
+abort: Fix up the change and run hg histedit --continue
+% fix up
+d
+***
+does not commute with e
+
+
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+file e already exists
+1 out of 1 hunks FAILED -- saving rejects to file e.rej
+abort: Fix up the change and run hg histedit --continue
+
+% just continue this time
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% log after edit
+@ changeset: 4:f768fd60ca34
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 3:671efe372e33
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% contents of e
+a
+% manifest
+a
+b
+c
+d
+e
+f
+% EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-fold.out Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,74 @@
+% log before edit
+@ changeset: 5:652413bf663e
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:e860deea161a
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% edit the history
+0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% log after edit
+@ changeset: 4:82b0c1ff1777
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 3:150aafb44a91
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: pick e860deea161a e
+|
+o changeset: 2:493dc0964412
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% post-fold manifest
+a
+b
+c
+d
+e
+f
+% EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-no-change Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,110 @@
+#!/bin/sh
+
+# test for issue #6:
+# editing a changeset without any actual change would corrupt the repository
+
+. "$TESTDIR/histedit-helpers.sh"
+
+cat >> $HGRCPATH <<EOF
+[extensions]
+graphlog=
+histedit=
+EOF
+
+initrepo ()
+{
+ dir="$1"
+ comment="$2"
+
+ if [ -n "${comment}" ]; then
+ echo % ${comment}
+ echo % ${comment} | sed 's:.:-:g'
+ fi
+
+ hg init ${dir}
+ cd ${dir}
+ for x in a b c d e f ; do
+ echo $x > $x
+ hg add $x
+ hg ci -m $x
+ done
+}
+
+geneditor ()
+{
+ # generate an editor script for selecting changesets to be edited
+
+ choice=$1 # changesets that should be edited (using sed line ranges)
+
+ cat <<EOF | sed 's:^....::'
+ #!/bin/sh
+
+ # editing the rules, replacing 'pick' with 'edit' for the chosen lines
+ sed '${choice}s:^pick:edit:' \$1 > \${1}.tmp
+ mv \${1}.tmp \$1
+
+ # displaying the resulting rules, minus comments and empty lines
+ sed '/^#/d;/^$/d;s:^:| :' \$1 >&2
+EOF
+}
+
+startediting ()
+{
+ # begin an editing session
+
+ choice="$1" # changesets that should be edited
+ number="$2" # number of changesets considered (from tip)
+ comment="$3"
+
+ geneditor "${choice}" > edit.sh
+ chmod +x edit.sh
+
+ echo % start editing the history ${comment}
+ HGEDITOR=./edit.sh hg histedit -- -${number} 2>&1 | fixbundle
+}
+
+continueediting ()
+{
+ # continue an edit already in progress
+
+ editor="$1" # message editor when finalizing editing
+ comment="$2"
+
+ echo % finalize changeset editing ${comment}
+ HGEDITOR=${editor} hg histedit --continue 2>&1 | fixbundle
+}
+
+graphlog ()
+{
+ comment="${1:-log}"
+
+ echo % "${comment}"
+ hg glog --template '{rev} {node} \"{desc|firstline}\"\n'
+}
+
+
+
+initrepo r1 "test editing with no change"
+graphlog "log before editing"
+startediting 2 3 "(not changing anything)" # edit the 2nd of 3 changesets
+continueediting true "(leaving commit message unaltered)"
+
+echo "% check state of working copy"
+hg id
+
+graphlog "log after history editing"
+
+
+cd ..
+initrepo r2 "test editing with no change, then abort"
+graphlog "log before editing"
+startediting 1,2 3 "(not changing anything)" # edit the 1st two of 3 changesets
+continueediting true "(leaving commit message unaltered)"
+graphlog "log after first edit"
+
+echo % abort editing session
+hg histedit --abort 2>&1 | fixbundle
+
+graphlog "log after abort"
+
+echo % EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-no-change.out Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,94 @@
+% test editing with no change
+-----------------------------
+% log before editing
+@ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
+|
+o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
+|
+o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
+|
+o 2 177f92b773850b59254aa5e923436f921b55483b "c"
+|
+o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
+|
+o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
+
+% start editing the history (not changing anything)
+| pick 055a42cdd887 3 d
+| edit e860deea161a 4 e
+| pick 652413bf663e 5 f
+0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+abort: Make changes as needed, you may commit or record as needed now.
+When you are finished, run hg histedit --continue to resume.
+% finalize changeset editing (leaving commit message unaltered)
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% check state of working copy
+652413bf663e tip
+% log after history editing
+@ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
+|
+o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
+|
+o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
+|
+o 2 177f92b773850b59254aa5e923436f921b55483b "c"
+|
+o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
+|
+o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
+
+% test editing with no change, then abort
+-----------------------------------------
+% log before editing
+@ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
+|
+o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
+|
+o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
+|
+o 2 177f92b773850b59254aa5e923436f921b55483b "c"
+|
+o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
+|
+o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
+
+% start editing the history (not changing anything)
+| edit 055a42cdd887 3 d
+| edit e860deea161a 4 e
+| pick 652413bf663e 5 f
+0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+abort: Make changes as needed, you may commit or record as needed now.
+When you are finished, run hg histedit --continue to resume.
+% finalize changeset editing (leaving commit message unaltered)
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+abort: Make changes as needed, you may commit or record as needed now.
+When you are finished, run hg histedit --continue to resume.
+% log after first edit
+o 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
+|
+o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
+|
+@ 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
+|
+o 2 177f92b773850b59254aa5e923436f921b55483b "c"
+|
+o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
+|
+o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
+
+% abort editing session
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% log after abort
+@ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
+|
+o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
+|
+o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
+|
+o 2 177f92b773850b59254aa5e923436f921b55483b "c"
+|
+o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
+|
+o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
+
+% EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-non-commute Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,90 @@
+#!/bin/sh
+
+. "$TESTDIR/histedit-helpers.sh"
+
+cat >> $HGRCPATH <<EOF
+[extensions]
+graphlog=
+histedit=
+EOF
+
+EDITED=`pwd`/editedhistory
+cat > $EDITED <<EOF
+pick 177f92b77385 c
+pick 055a42cdd887 d
+pick bfa474341cc9 does not commute with e
+pick e860deea161a e
+pick 652413bf663e f
+EOF
+initrepo ()
+{
+ hg init r
+ cd r
+ for x in a b c d e f ; do
+ echo $x > $x
+ hg add $x
+ hg ci -m $x
+ done
+ echo a >> e
+ hg ci -m 'does not commute with e'
+}
+
+initrepo
+
+echo % log before edit
+hg log --graph
+
+echo % edit the history
+HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
+
+echo % abort the edit
+hg histedit --abort 2>&1 | fixbundle
+
+echo
+echo
+echo % second edit set
+
+hg log --graph
+
+echo % edit the history
+HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
+
+echo % fix up
+echo a > e
+hg add e
+hg histedit --continue 2>&1 | fixbundle
+
+echo
+echo % just continue this time
+hg histedit --continue 2>&1 | fixbundle
+
+echo % log after edit
+hg log --graph
+
+echo % start over
+
+cd ..
+rm -r r
+initrepo
+cat > $EDITED <<EOF
+pick 177f92b77385 c
+pick 055a42cdd887 d
+mess bfa474341cc9 does not commute with e
+pick e860deea161a e
+pick 652413bf663e f
+EOF
+
+echo % edit the history, this time with a fold action
+HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
+
+echo
+echo a > e
+hg add e
+HGEDITOR="cat $EDITED > " hg histedit --continue 2>&1 | fixbundle
+echo % second edit also fails, but just continue
+hg histedit --continue 2>&1 | fixbundle
+
+echo % post message fix
+hg log --graph
+
+echo % EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-non-commute-abort Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+. "$TESTDIR/histedit-helpers.sh"
+
+cat >> $HGRCPATH <<EOF
+[extensions]
+graphlog=
+histedit=
+EOF
+
+EDITED=`pwd`/editedhistory
+cat > $EDITED <<EOF
+pick 177f92b77385 c
+pick 055a42cdd887 d
+pick bfa474341cc9 does not commute with e
+pick e860deea161a e
+pick 652413bf663e f
+EOF
+initrepo ()
+{
+ hg init r
+ cd r
+ for x in a b c d e f ; do
+ echo $x > $x
+ hg add $x
+ hg ci -m $x
+ done
+ echo a >> e
+ hg ci -m 'does not commute with e'
+}
+
+initrepo
+
+echo % log before edit
+hg log --graph
+
+echo % edit the history
+HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
+
+echo '% fix up (pre abort)'
+echo a > e
+hg add e
+hg histedit --continue 2>&1 | fixbundle
+
+echo % abort the edit
+hg histedit --abort 2>&1 | fixbundle
+
+echo % log after abort
+hg log --graph
+echo % EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-non-commute-abort.out Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,86 @@
+% log before edit
+@ changeset: 6:bfa474341cc9
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: does not commute with e
+|
+o changeset: 5:652413bf663e
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:e860deea161a
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% edit the history
+0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+1 out of 1 hunks FAILED -- saving rejects to file e.rej
+abort: Fix up the change and run hg histedit --continue
+% fix up (pre abort)
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+file e already exists
+1 out of 1 hunks FAILED -- saving rejects to file e.rej
+abort: Fix up the change and run hg histedit --continue
+% abort the edit
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% log after abort
+@ changeset: 6:bfa474341cc9
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: does not commute with e
+|
+o changeset: 5:652413bf663e
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:e860deea161a
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-non-commute.out Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,173 @@
+% log before edit
+@ changeset: 6:bfa474341cc9
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: does not commute with e
+|
+o changeset: 5:652413bf663e
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:e860deea161a
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% edit the history
+0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+1 out of 1 hunks FAILED -- saving rejects to file e.rej
+abort: Fix up the change and run hg histedit --continue
+% abort the edit
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+% second edit set
+@ changeset: 6:bfa474341cc9
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: does not commute with e
+|
+o changeset: 5:652413bf663e
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:e860deea161a
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: e
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% edit the history
+0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+1 out of 1 hunks FAILED -- saving rejects to file e.rej
+abort: Fix up the change and run hg histedit --continue
+% fix up
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+file e already exists
+1 out of 1 hunks FAILED -- saving rejects to file e.rej
+abort: Fix up the change and run hg histedit --continue
+
+% just continue this time
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% log after edit
+@ changeset: 5:9ab84894b459
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:1fff3ae8199d
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: does not commute with e
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% start over
+% edit the history, this time with a fold action
+0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+1 out of 1 hunks FAILED -- saving rejects to file e.rej
+abort: Fix up the change and run hg histedit --continue
+
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+file e already exists
+1 out of 1 hunks FAILED -- saving rejects to file e.rej
+abort: Fix up the change and run hg histedit --continue
+% second edit also fails, but just continue
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% post message fix
+@ changeset: 5:6459970fb49b
+| tag: tip
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: f
+|
+o changeset: 4:556f27c874b0
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: pick 177f92b77385 c
+|
+o changeset: 3:055a42cdd887
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: d
+|
+o changeset: 2:177f92b77385
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: c
+|
+o changeset: 1:d2ae7f538514
+| user: test
+| date: Thu Jan 01 00:00:00 1970 +0000
+| summary: b
+|
+o changeset: 0:cb9a9f314b8b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: a
+
+% EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-outgoing Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+cat >> $HGRCPATH <<EOF
+[extensions]
+graphlog=
+histedit=
+EOF
+
+EDITED=`pwd`/editedhistory
+cat > $EDITED <<EOF
+pick 177f92b77385 c
+pick e860deea161a e
+pick 652413bf663e f
+pick 055a42cdd887 d
+EOF
+initrepo ()
+{
+ hg init r
+ cd r
+ for x in a b c ; do
+ echo $x > $x
+ hg add $x
+ hg ci -m $x
+ done
+
+ cd ..
+ hg clone r r2 | grep -v updating
+ cd r2
+ for x in d e f ; do
+ echo $x > $x
+ hg add $x
+ hg ci -m $x
+ done
+
+ cd ..
+ hg init r3
+ cd r3
+ for x in g h i ; do
+ echo $x > $x
+ hg add $x
+ hg ci -m $x
+ done
+ cd ..
+}
+
+initrepo
+
+echo % show the edit commands offered by outgoing
+cd r2
+HGEDITOR=cat hg histedit --outgoing ../r | grep -v comparing | grep -v searching
+cd ..
+
+echo % show the error from unrelated repos
+cd r3
+HGEDITOR=cat hg histedit --outgoing ../r | grep -v comparing | grep -v searching
+cd ..
+
+echo % show the error from unrelated repos
+cd r3
+HGEDITOR=cat hg histedit --force --outgoing ../r
+cd ..
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-outgoing.out Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,36 @@
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% show the edit commands offered by outgoing
+pick 055a42cdd887 3 d
+pick e860deea161a 4 e
+pick 652413bf663e 5 f
+
+# Edit history between 055a42cdd887 and 652413bf663e
+#
+# Commands:
+# p, pick = use commit
+# e, edit = use commit, but stop for amending
+# f, fold = use commit, but fold into previous commit (combines N and N-1)
+# d, drop = remove commit from history
+# m, mess = edit message without changing commit content
+#
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% show the error from unrelated repos
+abort: repository is unrelated
+% show the error from unrelated repos
+comparing with ../r
+searching for changes
+warning: repository is unrelated
+pick 2a4042b45417 0 g
+pick 68c46b4927ce 1 h
+pick 51281e65ba79 2 i
+
+# Edit history between 2a4042b45417 and 51281e65ba79
+#
+# Commands:
+# p, pick = use commit
+# e, edit = use commit, but stop for amending
+# f, fold = use commit, but fold into previous commit (combines N and N-1)
+# d, drop = remove commit from history
+# m, mess = edit message without changing commit content
+#
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-histedit-revspec.t Wed Jun 27 17:52:54 2012 -0500
@@ -0,0 +1,62 @@
+This test requires parentrevspec support in revsets, so check for that
+and skip the test if we're on an unusual hg that supports .t tests but
+not parentrevspec.
+ $ python -c 'from mercurial import revset ; revset.methods["parentpost"]' || exit 80
+
+Enable extensions used by this test.
+ $ cat >>$HGRCPATH <<EOF
+ > [extensions]
+ > graphlog=
+ > histedit=
+ > EOF
+
+Repo setup.
+ $ hg init foo
+ $ cd foo
+ $ echo alpha >> alpha
+ $ hg addr
+ adding alpha
+ $ hg ci -m one
+ $ echo alpha >> alpha
+ $ hg ci -m two
+ $ echo alpha >> alpha
+ $ hg ci -m three
+ $ echo alpha >> alpha
+ $ hg ci -m four
+ $ echo alpha >> alpha
+ $ hg ci -m five
+
+ $ hg log --style compact --graph
+ @ 4[tip] 08d98a8350f3 1970-01-01 00:00 +0000 test
+ | five
+ |
+ o 3 c8e68270e35a 1970-01-01 00:00 +0000 test
+ | four
+ |
+ o 2 eb57da33312f 1970-01-01 00:00 +0000 test
+ | three
+ |
+ o 1 579e40513370 1970-01-01 00:00 +0000 test
+ | two
+ |
+ o 0 6058cbb6cfd7 1970-01-01 00:00 +0000 test
+ one
+
+
+Run a dummy edit to make sure we get tip^^ correctly via revsingle.
+ $ HGEDITOR=cat hg histedit tip^^
+ pick eb57da33312f 2 three
+ pick c8e68270e35a 3 four
+ pick 08d98a8350f3 4 five
+
+ # Edit history between eb57da33312f and 08d98a8350f3
+ #
+ # Commands:
+ # p, pick = use commit
+ # e, edit = use commit, but stop for amending
+ # f, fold = use commit, but fold into previous commit (combines N and N-1)
+ # d, drop = remove commit from history
+ # m, mess = edit message without changing commit content
+ #
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+