rebase: prevent creating divergence
Before this patch rebase would create divergence when you were rebasing obsolete
changesets on a destination not containing one of its successors.
This patch introduces rebase.allowdivergence to explicitly allow
divergence creation with rebase.
--- a/hgext/rebase.py Wed Jan 06 12:55:56 2016 -0800
+++ b/hgext/rebase.py Tue Jan 12 13:43:41 2016 -0800
@@ -350,6 +350,17 @@
dest)
rebaseobsskipped = set(obsoletenotrebased)
+ # Obsolete node with successors not in dest leads to divergence
+ divergenceok = ui.configbool('rebase',
+ 'allowdivergence')
+ divergencebasecandidates = rebaseobsrevs - rebaseobsskipped
+
+ if divergencebasecandidates and not divergenceok:
+ msg = _("this rebase will cause divergence")
+ h = _("to force the rebase please set "
+ "rebase.allowdivergence=True")
+ raise error.Abort(msg, hint=h)
+
# - plain prune (no successor) changesets are rebased
# - split changesets are not rebased if at least one of the
# changeset resulting from the split is an ancestor of dest
--- a/mercurial/help/config.txt Wed Jan 06 12:55:56 2016 -0800
+++ b/mercurial/help/config.txt Tue Jan 12 13:43:41 2016 -0800
@@ -1323,6 +1323,13 @@
``assume-tty``
If true, ALWAYS show a progress bar, unless disable is given.
+``rebase``
+----------
+
+``allowdivergence``
+ Default to False, when True allow creating divergence when performing
+ rebase of obsolete changesets.
+
``revsetalias``
---------------
--- a/tests/test-rebase-obsolete.t Wed Jan 06 12:55:56 2016 -0800
+++ b/tests/test-rebase-obsolete.t Tue Jan 12 13:43:41 2016 -0800
@@ -712,3 +712,96 @@
abort: all requested changesets have equivalents or were marked as obsolete
(to force the rebase, set the config experimental.rebaseskipobsolete to False)
[255]
+
+If a rebase is going to create divergence, it should abort
+
+ $ hg log -G
+ @ 11:f44da1f4954c nonrelevant
+ |
+ | o 10:121d9e3bc4c6 P
+ |/
+ o 9:4be60e099a77 C
+ |
+ o 6:9c48361117de D
+ |
+ o 2:261e70097290 B2
+ |
+ o 0:4a2df7238c3b A
+
+
+ $ hg up 9
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ echo "john" > doe
+ $ hg add doe
+ $ hg commit -m "john doe"
+ created new head
+ $ hg up 10
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ echo "foo" > bar
+ $ hg add bar
+ $ hg commit --amend -m "10'"
+ $ hg up 10 --hidden
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ echo "bar" > foo
+ $ hg add foo
+ $ hg commit -m "bar foo"
+ $ hg log -G
+ @ 15:73568ab6879d bar foo
+ |
+ | o 14:77d874d096a2 10'
+ | |
+ | | o 12:3eb461388009 john doe
+ | |/
+ x | 10:121d9e3bc4c6 P
+ |/
+ o 9:4be60e099a77 C
+ |
+ o 6:9c48361117de D
+ |
+ o 2:261e70097290 B2
+ |
+ o 0:4a2df7238c3b A
+
+ $ hg summary
+ parent: 15:73568ab6879d tip
+ bar foo
+ branch: default
+ commit: (clean)
+ update: 2 new changesets, 3 branch heads (merge)
+ phases: 8 draft
+ unstable: 1 changesets
+ $ hg rebase -s 10 -d 12
+ abort: this rebase will cause divergence
+ (to force the rebase please set rebase.allowdivergence=True)
+ [255]
+ $ hg log -G
+ @ 15:73568ab6879d bar foo
+ |
+ | o 14:77d874d096a2 10'
+ | |
+ | | o 12:3eb461388009 john doe
+ | |/
+ x | 10:121d9e3bc4c6 P
+ |/
+ o 9:4be60e099a77 C
+ |
+ o 6:9c48361117de D
+ |
+ o 2:261e70097290 B2
+ |
+ o 0:4a2df7238c3b A
+
+With rebase.allowdivergence=True, rebase can create divergence
+
+ $ hg rebase -s 10 -d 12 --config rebase.allowdivergence=True
+ rebasing 10:121d9e3bc4c6 "P"
+ rebasing 15:73568ab6879d "bar foo" (tip)
+ $ hg summary
+ parent: 17:61bd55f69bc4 tip
+ bar foo
+ branch: default
+ commit: (clean)
+ update: 1 new changesets, 2 branch heads (merge)
+ phases: 8 draft
+ divergent: 2 changesets
+