[PATCH 3 of 3] rebase: do not consider extincts for divergence detection (issue5782)
Denis Laxalde
denis at laxalde.org
Sat Feb 10 04:28:08 EST 2018
# HG changeset patch
# User Denis Laxalde <denis at laxalde.org>
# Date 1518212960 -3600
# Fri Feb 09 22:49:20 2018 +0100
# Node ID efb6929261e3fc640941c1b8fc9b0e378722d379
# Parent 864f2bc67aa90f1ae762206925906950b6258c2f
# EXP-Topic issue5782
rebase: do not consider extincts for divergence detection (issue5782)
Extinct obsolete changesets cannot cause divergence upon rebase. We
compute these obsoletes without a non-obsolete successor (extincts) in
_computeobsoletenotrebased() and then filter them out from the set of
obsolete revisions to rebase before getting into _checkobsrebase() to
check for divergence candidates.
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -312,10 +312,13 @@ class rebaseruntime(object):
if not self.ui.configbool('experimental', 'rebaseskipobsolete'):
return
obsoleteset = set(obsoleterevs)
- self.obsoletenotrebased, self.obsoletewithoutsuccessorindestination = \
- _computeobsoletenotrebased(self.repo, obsoleteset, destmap)
+ (self.obsoletenotrebased,
+ self.obsoletewithoutsuccessorindestination,
+ obsoleteextinctsuccessors) = _computeobsoletenotrebased(
+ self.repo, obsoleteset, destmap)
skippedset = set(self.obsoletenotrebased)
skippedset.update(self.obsoletewithoutsuccessorindestination)
+ skippedset.update(obsoleteextinctsuccessors)
_checkobsrebase(self.repo, self.ui, obsoleteset, skippedset)
def _prepareabortorcontinue(self, isabort):
@@ -1221,7 +1224,7 @@ def _checkobsrebase(repo, ui, rebaseobsr
`rebaseobsrevs`: set of obsolete revision in source
`rebaseobsskipped`: set of revisions from source skipped because they have
- successors in destination
+ successors in destination or no non-obsolete successor.
"""
# Obsolete node with successors not in dest leads to divergence
divergenceok = ui.configbool('experimental',
@@ -1786,13 +1789,18 @@ def _computeobsoletenotrebased(repo, reb
`obsoletewithoutsuccessorindestination` is a set with obsolete revisions
without a successor in destination.
+
+ `obsoleteextinctsuccessors` is a set of obsolete revisions with only
+ obsolete successors.
"""
obsoletenotrebased = {}
obsoletewithoutsuccessorindestination = set([])
+ obsoleteextinctsuccessors = set([])
assert repo.filtername is None
cl = repo.changelog
nodemap = cl.nodemap
+ extinctnodes = set(cl.node(r) for r in repo.revs('extinct()'))
for srcrev in rebaseobsrevs:
srcnode = cl.node(srcrev)
destnode = cl.node(destmap[srcrev])
@@ -1800,6 +1808,9 @@ def _computeobsoletenotrebased(repo, reb
successors = list(obsutil.allsuccessors(repo.obsstore, [srcnode]))
# obsutil.allsuccessors includes node itself
successors.remove(srcnode)
+ if set(successors).issubset(extinctnodes):
+ # all successors are extinct
+ obsoleteextinctsuccessors.add(srcrev)
if not successors:
# no successor
obsoletenotrebased[srcrev] = None
@@ -1817,7 +1828,11 @@ def _computeobsoletenotrebased(repo, reb
if any(nodemap[s] in destmap for s in successors):
obsoletewithoutsuccessorindestination.add(srcrev)
- return obsoletenotrebased, obsoletewithoutsuccessorindestination
+ return (
+ obsoletenotrebased,
+ obsoletewithoutsuccessorindestination,
+ obsoleteextinctsuccessors,
+ )
def summaryhook(ui, repo):
if not repo.vfs.exists('rebasestate'):
diff --git a/tests/test-rebase-obsolete.t b/tests/test-rebase-obsolete.t
--- a/tests/test-rebase-obsolete.t
+++ b/tests/test-rebase-obsolete.t
@@ -1244,10 +1244,6 @@ issue5782
o 0:b173517d0057 a
$ hg rebase -d 0 -r 2
- abort: this rebase will cause divergences from: a82ac2b38757
- (to force the rebase please set experimental.evolution.allowdivergence=True)
- [255]
- $ hg rebase -d 0 -r 2 --config experimental.evolution.allowdivergence=True
rebasing 2:a82ac2b38757 "c" (c)
$ hg log -G -r 'a': --hidden
o 5:69ad416a4a26 c
More information about the Mercurial-devel
mailing list