Mercurial > public > mercurial-scm > evolve
diff hgext/evolve.py @ 265:24943df310d4
amend: do not traceback on no-ops
If rewrite() generated changeset happened to be an existing one, the
call would traceback when trying to obsolete the changeset with itself.
Instead, leave gracefully, marking any intermediate changeset extinct.
author | Patrick Mezard <patrick@mezard.eu> |
---|---|
date | Tue, 12 Jun 2012 13:28:39 +0200 |
parents | 1c21865bf8ba |
children | 2da5af3dadeb |
line wrap: on
line diff
--- 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: