--- a/hgext/evolve.py Tue Jun 12 11:53:02 2012 +0200
+++ b/hgext/evolve.py Tue Jun 12 13:28:39 2012 +0200
@@ -57,6 +57,11 @@
#############################
def rewrite(repo, old, updates, head, newbases, commitopts):
+ """Return (nodeid, created) where nodeid is the identifier of the
+ changeset generated by the rewrite process, and created is True if
+ nodeid was actually created. If created is False, nodeid
+ references a changeset existing before the rewrite call.
+ """
if len(old.parents()) > 1: #XXX remove this unecessary limitation.
raise error.Abort(_('cannot amend merge changesets'))
base = old.p1()
@@ -126,29 +131,35 @@
if commitopts.get('edit'):
new._text = cmdutil.commitforceeditor(repo, new, [])
+ revcount = len(repo)
newid = repo.commitctx(new)
new = repo[newid]
-
- # update the bookmark
- if bm:
- repo._bookmarks[bm] = newid
- bookmarks.write(repo)
+ created = len(repo) != revcount
+ if created:
+ # update the bookmark
+ if bm:
+ repo._bookmarks[bm] = newid
+ bookmarks.write(repo)
- # add evolution metadata
- repo.addobsolete(new.node(), old.node())
- for u in updates:
- repo.addobsolete(u.node(), old.node())
- repo.addobsolete(new.node(), u.node())
- oldbookmarks = repo.nodebookmarks(old.node())
- for book in oldbookmarks:
- repo._bookmarks[book] = new.node()
- if oldbookmarks:
- bookmarks.write(repo)
-
+ # add evolution metadata
+ repo.addobsolete(new.node(), old.node())
+ for u in updates:
+ repo.addobsolete(u.node(), old.node())
+ repo.addobsolete(new.node(), u.node())
+ oldbookmarks = repo.nodebookmarks(old.node())
+ for book in oldbookmarks:
+ repo._bookmarks[book] = new.node()
+ if oldbookmarks:
+ bookmarks.write(repo)
+ else:
+ # newid is an existing revision. It could make sense to
+ # replace revisions with existing ones but probably not by
+ # default.
+ pass
finally:
wlock.release()
- return newid
+ return newid, created
def relocate(repo, orig, dest):
"""rewrite <rev> on dest"""
@@ -407,7 +418,11 @@
def commitfunc(ui, repo, message, match, opts):
return repo.commit(message, opts.get('user'), opts.get('date'), match,
editor=e)
- cmdutil.commit(ui, repo, commitfunc, pats, ciopts)
+ revcount = len(repo)
+ tempid = cmdutil.commit(ui, repo, commitfunc, pats, ciopts)
+ if len(repo) == revcount:
+ # No revision created
+ tempid = None
# find all changesets to be considered updates
cl = repo.changelog
@@ -429,13 +444,20 @@
# perform amend
if opts.get('edit'):
opts['force_editor'] = True
- newid = rewrite(repo, old, updates, head,
- [old.p1().node(), old.p2().node()], opts)
-
- # reroute the working copy parent to the new changeset
- phases.retractboundary(repo, oldphase, [newid])
- repo.dirstate.setparents(newid, node.nullid)
-
+ newid, created = rewrite(repo, old, updates, head,
+ [old.p1().node(), old.p2().node()], opts)
+ if created:
+ # reroute the working copy parent to the new changeset
+ phases.retractboundary(repo, oldphase, [newid])
+ repo.dirstate.setparents(newid, node.nullid)
+ else:
+ # rewrite() recreated an existing revision, discard
+ # the intermediate revision if any. No need to update
+ # phases or parents.
+ if tempid is not None:
+ repo.addobsolete(node.nullid, tempid)
+ # XXX: need another message in collapse case.
+ raise error.Abort(_('no updates found'))
finally:
wlock.release()
finally:
--- a/tests/test-amend.t Tue Jun 12 11:53:02 2012 +0200
+++ b/tests/test-amend.t Tue Jun 12 13:28:39 2012 +0200
@@ -8,6 +8,10 @@
$ echo "obsolete=$(echo $(dirname $TESTDIR))/hgext/obsolete.py" >> $HGRCPATH
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext/evolve.py" >> $HGRCPATH
+ $ glog() {
+ > hg glog --template '{rev}@{branch}({phase}) {desc|firstline}\n' "$@"
+ > }
+
$ hg init repo
$ cd repo
$ echo a > a
@@ -25,7 +29,67 @@
$ hg branches
foo 2:a34b93d251e4
default 0:07f494440405 (inactive)
- $ hg glog --template '{rev}@{branch} {desc|firstline}\n'
- @ 2@foo adda
+ $ glog
+ @ 2@foo(draft) adda
+
+Test no-op
+
+ $ hg amend
+ abort: no updates found
+ [255]
+ $ glog
+ @ 2@foo(draft) adda
+
+
+Test forcing the message to the same value, no intermediate revision.
+
+ $ hg amend -m 'adda'
+ abort: no updates found
+ [255]
+ $ glog
+ @ 2@foo(draft) adda
+Test collapsing into an existing revision, no intermediate revision.
+
+ $ echo a >> a
+ $ hg ci -m changea
+ $ echo a > a
+ $ hg ci -m reseta
+ $ hg amend --change 2
+ abort: no updates found
+ [255]
+ $ hg phase 2
+ 2: draft
+ $ glog
+ @ 4@foo(draft) reseta
+ |
+ o 3@foo(draft) changea
+ |
+ o 2@foo(draft) adda
+
+
+Test collapsing into an existing rev, with an intermediate revision.
+
+ $ hg branch --force default
+ marked working directory as branch default
+ (branches are permanent and global, did you want a bookmark?)
+ $ hg ci -m resetbranch
+ created new head
+ $ hg branch --force foo
+ marked working directory as branch foo
+ (branches are permanent and global, did you want a bookmark?)
+ $ hg amend --change 2
+ abort: no updates found
+ [255]
+ $ glog
+ @ 6@foo(secret) amends a34b93d251e49c93d5685ebacad785c73a7e8605
+ |
+ o 5@default(draft) resetbranch
+ |
+ o 4@foo(draft) reseta
+ |
+ o 3@foo(draft) changea
+ |
+ o 2@foo(draft) adda
+