D10249: rebase: filter out descendants of divergence-causing commits earlier
martinvonz (Martin von Zweigbergk)
phabricator at mercurial-scm.org
Mon Mar 22 17:37:15 UTC 2021
martinvonz created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.
REVISION SUMMARY
`hg rebase` treats obsolete commits differently depending what has
happened to the commit:
1. Obsolete commit without non-obsolete successors: Skipped, and a note is printed ("it has no successor").
2. Obsolete commit with a successor in the destination (ancestor of it): Skipped, and a note is printed ("already in destination").
3. Obsolete commit with a successor in the rebase set: Error ("this rebase will cause divergences"), unless `allowdivergence` config set.
4. Obsolete commit with a succesor elsewhere: The commit and its descendants are skipped, and a note is printed ("not rebasing <commit> and its descedants as this would cause divergence"), unless `allowdivergence` config set.
Before this patch, we did all those checks up front, except for (4),
which was checked later. The later check consisted of two parts: 1)
filtering out of descendants, and 2) conditionally printing message if
the `allowdivergence` config was not set. This patch makes it so we do
the filtering early.
A consequence of filtering out divergence-causing commits earlier is
that we rebase commits in slightly different order, which has some
impact on tests.
REPOSITORY
rHG Mercurial
BRANCH
default
REVISION DETAIL
https://phab.mercurial-scm.org/D10249
AFFECTED FILES
hgext/rebase.py
tests/test-rebase-obsolete.t
CHANGE DETAILS
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
@@ -1098,9 +1098,9 @@
$ hg rebase -b 'e' -d 'x'
rebasing 1:488e1b7e7341 b "b"
rebasing 3:a82ac2b38757 c "c"
+ note: not rebasing 4:76be324c128b d "d" and its descendants as this would cause divergence
rebasing 5:027ad6c5830d d' "d'"
rebasing 6:d60ebfa0f1cb e "e"
- note: not rebasing 4:76be324c128b d "d" and its descendants as this would cause divergence
$ hg log -G -r 'a'::
o 11:eb6d63fc4ed5 e
|
@@ -1233,16 +1233,16 @@
$ hg rebase -b 'f' -d 'x'
rebasing 1:488e1b7e7341 b "b"
rebasing 3:a82ac2b38757 c "c"
- rebasing 5:63324dc512ea e' "e'"
- rebasing 7:3ffec603ab53 f "f"
rebasing 4:76be324c128b d "d"
note: not rebasing 6:e36fae928aec e "e" and its descendants as this would cause divergence
+ rebasing 5:63324dc512ea e' "e'"
+ rebasing 7:3ffec603ab53 f "f"
$ hg log -G -r 'a':
- o 13:a1707a5b7c2c d
+ o 13:ef6251596616 f
|
- | o 12:ef6251596616 f
- | |
- | o 11:b6f172e64af9 e'
+ o 12:b6f172e64af9 e'
+ |
+ | o 11:a1707a5b7c2c d
|/
o 10:d008e6b4d3fd c
|
@@ -1250,13 +1250,13 @@
|
| * 8:2876ce66c6eb g
| |
- | | x 7:3ffec603ab53 f (rewritten using rebase as 12:ef6251596616)
+ | | x 7:3ffec603ab53 f (rewritten using rebase as 13:ef6251596616)
| | |
| x | 6:e36fae928aec e (rewritten using replace as 5:63324dc512ea)
| | |
- | | x 5:63324dc512ea e' (rewritten using rebase as 11:b6f172e64af9)
+ | | x 5:63324dc512ea e' (rewritten using rebase as 12:b6f172e64af9)
| | |
- | x | 4:76be324c128b d (rewritten using rebase as 13:a1707a5b7c2c)
+ | x | 4:76be324c128b d (rewritten using rebase as 11:a1707a5b7c2c)
| |/
| x 3:a82ac2b38757 c (rewritten using rebase as 10:d008e6b4d3fd)
| |
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -362,6 +362,19 @@
skippedset = set(self.obsolete_with_successor_in_destination)
skippedset.update(self.obsolete_would_cause_divergence)
_checkobsrebase(self.repo, self.ui, obsoleteset, skippedset)
+ allowdivergence = self.ui.configbool(
+ b'experimental', b'evolution.allowdivergence'
+ )
+ if allowdivergence:
+ self.obsolete_would_cause_divergence = set()
+ else:
+ for rev in self.repo.revs(
+ b'descendants(%ld) and not %ld',
+ self.obsolete_would_cause_divergence,
+ self.obsolete_would_cause_divergence,
+ ):
+ self.state.pop(rev, None)
+ self.destmap.pop(rev, None)
def _prepareabortorcontinue(
self, isabort, backup=True, suppwarns=False, dryrun=False, confirm=False
@@ -494,19 +507,10 @@
def progress(ctx):
p.increment(item=(b"%d:%s" % (ctx.rev(), ctx)))
- allowdivergence = self.ui.configbool(
- b'experimental', b'evolution.allowdivergence'
- )
for subset in sortsource(self.destmap):
sortedrevs = self.repo.revs(b'sort(%ld, -topo)', subset)
- if not allowdivergence:
- sortedrevs -= self.repo.revs(
- b'descendants(%ld) and not %ld',
- self.obsolete_would_cause_divergence,
- self.obsolete_would_cause_divergence,
- )
for rev in sortedrevs:
- self._rebasenode(tr, rev, allowdivergence, progress)
+ self._rebasenode(tr, rev, progress)
p.complete()
ui.note(_(b'rebase merging completed\n'))
@@ -568,15 +572,13 @@
return newnode
- def _rebasenode(self, tr, rev, allowdivergence, progressfn):
+ def _rebasenode(self, tr, rev, progressfn):
repo, ui, opts = self.repo, self.ui, self.opts
ctx = repo[rev]
desc = _ctxdesc(ctx)
if self.state[rev] == rev:
ui.status(_(b'already rebased %s\n') % desc)
- elif (
- not allowdivergence and rev in self.obsolete_would_cause_divergence
- ):
+ elif rev in self.obsolete_would_cause_divergence:
msg = (
_(
b'note: not rebasing %s and its descendants as '
To: martinvonz, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
More information about the Mercurial-devel
mailing list