[PATCH 2 of 2] rebase: only pick branches without obsolete changeset with -b (issue5300)

Denis Laxalde denis at laxalde.org
Wed Aug 30 09:54:15 EDT 2017


# HG changeset patch
# User Denis Laxalde <denis at laxalde.org>
# Date 1504025723 -7200
#      Tue Aug 29 18:55:23 2017 +0200
# Node ID 092bccbfdc5d29fe5fe2f79c18d49bd842437707
# Parent  28e449777fb7452e569292184a18f358186248a3
rebase: only pick branches without obsolete changeset with -b (issue5300)

When trying to rebase the following graph with -b 24, the command will abort
because "this rebase will cause divergence from: 21".

  @  24
  |
  o  23
  |
  | o  22 (orphan)
  | |
  | x  21 (rewritten as 23)
  |/
  o  20

By computing the set of revisions to rebase excluding branches with changesets
that would get divergent, we let the rebase proceed (and rebase 20::24 in the
example above) while leaving already unstable branches (21::) behind. The
reason for leaving unstable things behind is that when the user explicitly
specifies the --base, we know which part of the graph they're interested in.

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -755,6 +755,8 @@ def _definesets(ui, repo, destf=None, sr
             roots += list(repo.revs('children(%d) & ancestors(%ld)', bp, bs))
 
         rebaseset = repo.revs('%ld::', roots)
+        if obsolete.isenabled(repo, obsolete.allowunstableopt):
+            rebaseset -= repo.revs('only(obsolete(), (%ld))::', base)
 
         if not rebaseset:
             # transform to list because smartsets are not comparable to
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
@@ -858,6 +858,89 @@ With experimental.allowdivergence=True, 
   phases: 8 draft
   content-divergent: 2 changesets
 
+rebase -b leaves branches with unstable changesets
+  $ hg log -G -T "{rev}:{node|short} {desc|firstline} ({instabilities})\n"
+  @  17:61bd55f69bc4 bar foo ()
+  |
+  o  16:5f53594f6882 P (content-divergent)
+  |
+  | o  14:77d874d096a2 10' (content-divergent)
+  | |
+  o |  12:3eb461388009 john doe ()
+  |/
+  o  9:4be60e099a77 C ()
+  |
+  o  6:9c48361117de D ()
+  |
+  o  2:261e70097290 B2 ()
+  |
+  o  0:4a2df7238c3b A ()
+  
+  $ hg up --quiet 6
+  $ echo X > X
+  $ hg add X
+  $ hg ci -mX
+  created new head
+  $ hg id -in
+  77b9c700c48f 18
+  $ echo Y > Y
+  $ hg add Y
+  $ hg ci -mY
+  $ hg id -in
+  3011703f72e2 19
+  $ hg up --quiet 18
+  $ echo Z > Z
+  $ hg add Z
+  $ hg ci -m Z
+  created new head
+  $ echo ZZ >> Z
+  $ hg ci -m ZZ
+  $ hg id -i
+  cdec77b938cb
+  $ echo Z? >> Z
+  $ hg ci -m WIP
+  $ hg up --quiet '.^'
+  $ hg ci --amend -m Zz
+  $ echo ZZZ > Z
+  $ hg ci -mZZZ
+  $ hg log -G -T "{rev}:{node|short} {desc|firstline} ({instabilities})\n"
+  @  24:cec38798f9cb ZZZ ()
+  |
+  o  23:d8c4115abbc7 Zz ()
+  |
+  | o  22:2238c5536cc2 WIP (orphan)
+  | |
+  | x  21:cdec77b938cb ZZ ()
+  |/
+  o  20:cb4bc2b895c2 Z ()
+  |
+  | o  19:3011703f72e2 Y ()
+  |/
+  o  18:77b9c700c48f X ()
+  |
+  | o  17:61bd55f69bc4 bar foo ()
+  | |
+  | o  16:5f53594f6882 P (content-divergent)
+  | |
+  | | o  14:77d874d096a2 10' (content-divergent)
+  | | |
+  | o |  12:3eb461388009 john doe ()
+  | |/
+  | o  9:4be60e099a77 C ()
+  |/
+  o  6:9c48361117de D ()
+  |
+  o  2:261e70097290 B2 ()
+  |
+  o  0:4a2df7238c3b A ()
+  
+  $ hg rebase -b . -d 19
+  rebasing 20:cb4bc2b895c2 "Z"
+  rebasing 23:d8c4115abbc7 "Zz"
+  rebasing 24:cec38798f9cb "ZZZ" (tip)
+  $ hg strip --config extensions.strip= --no-backup 18:: --quiet
+  $ hg up 17 --quiet
+
 rebase --continue + skipped rev because their successors are in destination
 we make a change in trunk and work on conflicting changes to make rebase abort.
 


More information about the Mercurial-devel mailing list