Mercurial > evolve
diff hgext/evolve.py @ 1106:6b0cf1b73693 stable
evolve: replace each obsolete sha1 in the description with its latest successor
Obsolete csets are hidden by default and don't get pushed to the parent repo.
In order to avoid broken references in commit messages, it makes sense to evolve
those references to the latest and greatest successor, as each cset containing
them is evolved. Of course, stale references can still occur if a commit in
branch 'A' references something in branch 'B', and that something in 'B' is
evolved but 'A' isn't subsequently evolved.
This alleviates the user that is evolving a series of commits from having to
1) recognize that there is a hash that needs updating in any one of the series
2) look up the latest successor manually
3) hg amend -e
The regular expression for matching and the logic for replacing are borrowed
from the convert extension [1].
It might be nice for the output to state the reason that the reference couldn't
be updated (it was pruned, split or diverged), but that may be excessive for
something only displayed in verbose mode. (Maybe it should be a ui.status()
instead?)
[1] http://selenic.com/hg/rev/45562379ce4e
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Sat, 09 Aug 2014 19:12:16 -0400 |
parents | cb36a4eb0157 |
children | 1c227ecb744d 212f24013455 |
line wrap: on
line diff
--- a/hgext/evolve.py Sat Aug 09 18:36:28 2014 -0400 +++ b/hgext/evolve.py Sat Aug 09 19:12:16 2014 -0400 @@ -27,6 +27,8 @@ from StringIO import StringIO import struct import urllib +import re +sha1re = re.compile(r'\b[0-9a-f]{6,40}\b') import mercurial from mercurial import util @@ -909,6 +911,32 @@ destbookmarks = repo.nodebookmarks(dest.node()) nodesrc = orig.node() destphase = repo[nodesrc].phase() + commitmsg = orig.description() + + cache = {} + sha1s = re.findall(sha1re, commitmsg) + unfi = repo.unfiltered() + for sha1 in sha1s: + ctx = None + try: + ctx = unfi[sha1] + except error.RepoLookupError: + continue + + if not ctx.obsolete(): + continue + + successors = obsolete.successorssets(repo, ctx.node(), cache) + + # We can't make any assumptions about how to update the hash if the + # cset in question was split or diverged. + if len(successors) == 1 and len(successors[0]) == 1: + newsha1 = node.hex(successors[0][0]) + commitmsg = commitmsg.replace(sha1, newsha1[:len(sha1)]) + else: + repo.ui.note(_('The stale commit message reference to %s could ' + 'not be updated') % sha1) + tr = repo.transaction('relocate') try: try: @@ -919,7 +947,7 @@ 'unresolved merge conflicts (see hg help resolve)') cmdutil.duplicatecopies(repo, orig.node(), dest.node()) nodenew = rebase.concludenode(repo, orig.node(), dest.node(), - node.nullid) + node.nullid, commitmsg) except util.Abort, exc: class LocalMergeFailure(MergeFailure, exc.__class__): pass