destutil: add the ability to specify a search space for rebase destination
In the 'hg pull --rebase', we don't want to pick a rebase destination unrelated
to the pull, we lay down basic infrastructure to allow such restriction on
stable (before 3.8 release) in this case. See issue 5214 for details.
Actual usage and test will be in the next patch.
--- a/hgext/rebase.py Sat Apr 30 09:26:47 2016 -0700
+++ b/hgext/rebase.py Sat Apr 30 18:41:08 2016 +0200
@@ -69,12 +69,12 @@
c(ctx, extra)
return extrafn
-def _destrebase(repo, sourceset):
+def _destrebase(repo, sourceset, destspace=None):
"""small wrapper around destmerge to pass the right extra args
Please wrap destutil.destmerge instead."""
return destutil.destmerge(repo, action='rebase', sourceset=sourceset,
- onheadcheck=False)
+ onheadcheck=False, destspace=destspace)
revsetpredicate = registrar.revsetpredicate()
@@ -222,6 +222,9 @@
srcf = opts.get('source', None)
basef = opts.get('base', None)
revf = opts.get('rev', [])
+ # search default destination in this space
+ # used in the 'hg pull --rebase' case, see issue 5214.
+ destspace = opts.get('_destspace')
contf = opts.get('continue')
abortf = opts.get('abort')
collapsef = opts.get('collapse', False)
@@ -296,7 +299,8 @@
_checkobsrebase(repo, ui, rebaseobsrevs, rebasesetrevs,
rebaseobsskipped)
else:
- dest, rebaseset = _definesets(ui, repo, destf, srcf, basef, revf)
+ dest, rebaseset = _definesets(ui, repo, destf, srcf, basef, revf,
+ destspace=destspace)
if dest is None:
return _nothingtorebase()
@@ -525,9 +529,12 @@
finally:
release(lock, wlock)
-def _definesets(ui, repo, destf=None, srcf=None, basef=None, revf=[]):
+def _definesets(ui, repo, destf=None, srcf=None, basef=None, revf=[],
+ destspace=None):
"""use revisions argument to define destination and rebase set
"""
+ # destspace is here to work around issues with `hg pull --rebase` see
+ # issue5214 for details
if srcf and basef:
raise error.Abort(_('cannot specify both a source and a base'))
if revf and basef:
@@ -560,7 +567,7 @@
"can't compute rebase set\n"))
return None, None
if not destf:
- dest = repo[_destrebase(repo, base)]
+ dest = repo[_destrebase(repo, base, destspace=destspace)]
destf = str(dest)
commonanc = repo.revs('ancestor(%ld, %d)', base, dest).first()
@@ -598,7 +605,7 @@
return None, None
if not destf:
- dest = repo[_destrebase(repo, rebaseset)]
+ dest = repo[_destrebase(repo, rebaseset, destspace=destspace)]
destf = str(dest)
return dest, rebaseset
--- a/mercurial/destutil.py Sat Apr 30 09:26:47 2016 -0700
+++ b/mercurial/destutil.py Sat Apr 30 18:41:08 2016 +0200
@@ -256,7 +256,7 @@
},
}
-def _destmergebook(repo, action='merge', sourceset=None):
+def _destmergebook(repo, action='merge', sourceset=None, destspace=None):
"""find merge destination in the active bookmark case"""
node = None
bmheads = repo.bookmarkheads(repo._activebookmark)
@@ -275,7 +275,8 @@
assert node is not None
return node
-def _destmergebranch(repo, action='merge', sourceset=None, onheadcheck=True):
+def _destmergebranch(repo, action='merge', sourceset=None, onheadcheck=True,
+ destspace=None):
"""find merge destination based on branch heads"""
node = None
@@ -308,6 +309,12 @@
bheads = list(repo.revs('%ln - (%ld::)', bheads, sourceset))
# filters out bookmarked heads
nbhs = list(repo.revs('%ld - bookmark()', bheads))
+
+ if destspace is not None:
+ # restrict search space
+ # used in the 'hg pull --rebase' case, see issue 5214.
+ nbhs = list(repo.revs('%ld and %ld', destspace, nbhs))
+
if len(nbhs) > 1:
# Case B: There is more than 1 other anonymous heads
#
@@ -339,18 +346,22 @@
assert node is not None
return node
-def destmerge(repo, action='merge', sourceset=None, onheadcheck=True):
+def destmerge(repo, action='merge', sourceset=None, onheadcheck=True,
+ destspace=None):
"""return the default destination for a merge
(or raise exception about why it can't pick one)
:action: the action being performed, controls emitted error message
"""
+ # destspace is here to work around issues with `hg pull --rebase` see
+ # issue5214 for details
if repo._activebookmark:
- node = _destmergebook(repo, action=action, sourceset=sourceset)
+ node = _destmergebook(repo, action=action, sourceset=sourceset,
+ destspace=destspace)
else:
node = _destmergebranch(repo, action=action, sourceset=sourceset,
- onheadcheck=onheadcheck)
+ onheadcheck=onheadcheck, destspace=destspace)
return repo[node].rev()
histeditdefaultrevset = 'reverse(only(.) and not public() and not ::merge())'