--- a/hgext/evolve.py Mon Jun 18 14:35:49 2012 +0200
+++ b/hgext/evolve.py Mon Jun 18 17:12:11 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()
@@ -112,6 +117,8 @@
user = commitopts.get('user') or old.user()
date = commitopts.get('date') or None # old.date()
+ extra = dict(commitopts.get('extra', {}))
+ extra['branch'] = head.branch()
new = context.memctx(repo,
parents=newbases,
@@ -120,33 +127,39 @@
filectxfn=filectxfn,
user=user,
date=date,
- extra=commitopts.get('extra') or None)
+ extra=extra)
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"""
@@ -352,8 +365,6 @@
_('use text as commit message for this update')),
('c', 'change', '',
_('specifies the changeset to amend'), _('REV')),
- ('b', 'branch', '',
- _('specifies a branch for the new.'), _('REV')),
('e', 'edit', False,
_('edit commit message.'), _('')),
] + walkopts + commitopts + commitopts2,
@@ -385,16 +396,10 @@
"""
# determine updates to subsume
- change = opts.get('change')
+ change = opts.get('change', '.')
if change == '.':
change = 'p1(p1())'
old = scmutil.revsingle(repo, change)
- branch = opts.get('branch')
- if branch:
- opts.setdefault('extra', {})['branch'] = branch
- else:
- if old.branch() != 'default':
- opts.setdefault('extra', {})['branch'] = old.branch()
lock = repo.lock()
try:
@@ -413,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
@@ -421,7 +430,7 @@
updatenodes = set(cl.nodesbetween(roots=[old.node()],
heads=[head.node()])[0])
updatenodes.remove(old.node())
- okoptions = ['message', 'logfile', 'edit', 'user', 'branch']
+ okoptions = ['message', 'logfile', 'edit', 'user']
if not updatenodes:
for o in okoptions:
if opts.get(o):
@@ -435,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: