Mercurial > public > mercurial-scm > hg-stable
diff mercurial/scmutil.py @ 33686:2f427b57bf90 stable 4.3.3
rebase: move bookmarks with --keep (issue5682)
This is a regression caused by 3b7cb3d17137. We have documented the behavior
in rebase help:
Rebase will destroy original commits unless you use "--keep". It will
also move your bookmarks (even if you do).
So let's restore the old behavior.
It is done by changing `scmutil.cleanupnodes` to accept more information so
a node could have different "movement destination" from "successors". It
also helps simplifying the callsite as a side effect - the special bookmark
movement logic in rebase is removed.
Differential Revision: https://phab.mercurial-scm.org/D727
author | Jun Wu <quark@fb.com> |
---|---|
date | Mon, 18 Sep 2017 10:54:00 -0700 |
parents | 2dbd6d259cd2 |
children | f61f5af5ed31 |
line wrap: on
line diff
--- a/mercurial/scmutil.py Wed Sep 20 09:32:26 2017 -0700 +++ b/mercurial/scmutil.py Mon Sep 18 10:54:00 2017 -0700 @@ -576,23 +576,34 @@ def __contains__(self, node): return self._revcontains(self._torev(node)) -def cleanupnodes(repo, replacements, operation): +def cleanupnodes(repo, replacements, operation, moves=None): """do common cleanups when old nodes are replaced by new nodes That includes writing obsmarkers or stripping nodes, and moving bookmarks. (we might also want to move working directory parent in the future) + By default, bookmark moves are calculated automatically from 'replacements', + but 'moves' can be used to override that. Also, 'moves' may include + additional bookmark moves that should not have associated obsmarkers. + replacements is {oldnode: [newnode]} or a iterable of nodes if they do not have replacements. operation is a string, like "rebase". """ + if not replacements and not moves: + return + + # translate mapping's other forms if not util.safehasattr(replacements, 'items'): replacements = {n: () for n in replacements} # Calculate bookmark movements - moves = {} + if moves is None: + moves = {} # Unfiltered repo is needed since nodes in replacements might be hidden. unfi = repo.unfiltered() for oldnode, newnodes in replacements.items(): + if oldnode in moves: + continue if len(newnodes) > 1: # usually a split, take the one with biggest rev number newnode = next(unfi.set('max(%ln)', newnodes)).node() @@ -646,10 +657,13 @@ rels = [(unfi[n], tuple(unfi[m] for m in s)) for n, s in sorted(replacements.items(), key=sortfunc) if s or not isobs(n)] - obsolete.createmarkers(repo, rels, operation=operation) + if rels: + obsolete.createmarkers(repo, rels, operation=operation) else: from . import repair # avoid import cycle - repair.delayedstrip(repo.ui, repo, list(replacements), operation) + tostrip = list(replacements) + if tostrip: + repair.delayedstrip(repo.ui, repo, tostrip, operation) def addremove(repo, matcher, prefix, opts=None, dry_run=None, similarity=None): if opts is None: