tests/test-rebase-obsolete3.t
author Pierre-Yves David <pierre-yves.david@octobus.net>
Fri, 05 Apr 2024 12:24:47 +0200
changeset 51582 d8287e43540f
parent 46834 535de0e34a79
permissions -rw-r--r--
phases: stop using `repo.set` in `remotephasessummary` The `repository.set` create changectx on the fly, an expensive operation. Using `repo.revs` and a direct rev-num → node-id translation will be significantly faster. This is especially true as we prepare ourself to no longer do the rev-num → node-id transalation there. The speedup is a bit lost in the overall noisyness of the slow phase discovery algorithm, but it save a small amount of time in my benchmark.

==========================
Test rebase with obsolete
==========================

Enable obsolete

  $ cat >> $HGRCPATH << EOF
  > [command-templates]
  > log= {rev}:{node|short} {desc|firstline}{if(obsolete,' ({obsfate})')}
  > [experimental]
  > evolution.createmarkers=True
  > evolution.allowunstable=True
  > [phases]
  > publish=False
  > [extensions]
  > rebase=
  > drawdag=$TESTDIR/drawdag.py
  > strip=
  > EOF

Divergence cases due to obsolete changesets
-------------------------------------------

We should ignore branches with unstable changesets when they are based on an
obsolete changeset which successor is in rebase set.

  $ hg init divergence
  $ cd divergence
  $ cat >> .hg/hgrc << EOF
  > [extensions]
  > strip =
  > [alias]
  > strip = strip --no-backup --quiet
  > [templates]
  > instabilities = '{rev}:{node|short} {desc|firstline}{if(instabilities," ({instabilities})")}\n'
  > EOF

  $ hg debugdrawdag <<EOF
  >   e   f
  >   |   |
  >   d'  d # replace: d -> d'
  >    \ /
  >     c
  >     |
  >   x b
  >    \|
  >     a
  > EOF
  1 new orphan changesets
  $ hg log -G -r 'a'::
  *  7:1143e9adc121 f
  |
  | o  6:d60ebfa0f1cb e
  | |
  | o  5:027ad6c5830d d'
  | |
  x |  4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
  |/
  o  3:a82ac2b38757 c
  |
  | o  2:630d7c95eff7 x
  | |
  o |  1:488e1b7e7341 b
  |/
  o  0:b173517d0057 a
  

Changeset d and its descendants are excluded to avoid divergence of d, which
would occur because the successor of d (d') is also in rebaseset. As a
consequence f (descendant of d) is left behind.

  $ 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"
  $ hg log -G -r 'a'::
  o  11:eb6d63fc4ed5 e
  |
  o  10:44d8c724a70c d'
  |
  o  9:d008e6b4d3fd c
  |
  o  8:67e8f4a16c49 b
  |
  | *  7:1143e9adc121 f
  | |
  | | x  6:d60ebfa0f1cb e (rewritten using rebase as 11:eb6d63fc4ed5)
  | | |
  | | x  5:027ad6c5830d d' (rewritten using rebase as 10:44d8c724a70c)
  | | |
  | x |  4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
  | |/
  | x  3:a82ac2b38757 c (rewritten using rebase as 9:d008e6b4d3fd)
  | |
  o |  2:630d7c95eff7 x
  | |
  | x  1:488e1b7e7341 b (rewritten using rebase as 8:67e8f4a16c49)
  |/
  o  0:b173517d0057 a
  
  $ hg strip -r 8:
  $ hg log -G -r 'a'::
  *  7:1143e9adc121 f
  |
  | o  6:d60ebfa0f1cb e
  | |
  | o  5:027ad6c5830d d'
  | |
  x |  4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
  |/
  o  3:a82ac2b38757 c
  |
  | o  2:630d7c95eff7 x
  | |
  o |  1:488e1b7e7341 b
  |/
  o  0:b173517d0057 a
  

If the rebase set has an obsolete (d) with a successor (d') outside the rebase
set and none in destination, we still get the divergence warning.
By allowing divergence, we can perform the rebase.

  $ hg rebase -r 'c'::'f' -d 'x'
  abort: this rebase will cause divergences from: 76be324c128b
  (to force the rebase please set experimental.evolution.allowdivergence=True)
  [20]
  $ hg rebase --config experimental.evolution.allowdivergence=true -r 'c'::'f' -d 'x'
  rebasing 3:a82ac2b38757 c "c"
  rebasing 4:76be324c128b d "d"
  rebasing 7:1143e9adc121 f tip "f"
  1 new orphan changesets
  2 new content-divergent changesets
  $ hg log -G -r 'a':: -T instabilities
  o  10:e1744ea07510 f
  |
  *  9:e2b36ea9a0a0 d (content-divergent)
  |
  o  8:6a0376de376e c
  |
  | x  7:1143e9adc121 f
  | |
  | | *  6:d60ebfa0f1cb e (orphan)
  | | |
  | | *  5:027ad6c5830d d' (orphan content-divergent)
  | | |
  | x |  4:76be324c128b d
  | |/
  | x  3:a82ac2b38757 c
  | |
  o |  2:630d7c95eff7 x
  | |
  | o  1:488e1b7e7341 b
  |/
  o  0:b173517d0057 a
  
  $ hg strip -r 8:

(Not skipping obsoletes means that divergence is allowed.)

  $ hg rebase --config experimental.rebaseskipobsolete=false -r 'c'::'f' -d 'x'
  rebasing 3:a82ac2b38757 c "c"
  rebasing 4:76be324c128b d "d"
  rebasing 7:1143e9adc121 f tip "f"
  1 new orphan changesets
  2 new content-divergent changesets

  $ hg strip -r 0:

Similar test on a more complex graph

  $ hg debugdrawdag <<EOF
  >       g
  >       |
  >   f   e
  >   |   |
  >   e'  d # replace: e -> e'
  >    \ /
  >     c
  >     |
  >   x b
  >    \|
  >     a
  > EOF
  1 new orphan changesets
  $ hg log -G -r 'a':
  *  8:2876ce66c6eb g
  |
  | o  7:3ffec603ab53 f
  | |
  x |  6:e36fae928aec e (rewritten using replace as 5:63324dc512ea)
  | |
  | o  5:63324dc512ea e'
  | |
  o |  4:76be324c128b d
  |/
  o  3:a82ac2b38757 c
  |
  | o  2:630d7c95eff7 x
  | |
  o |  1:488e1b7e7341 b
  |/
  o  0:b173517d0057 a
  
  $ hg rebase -b 'f' -d 'x'
  rebasing 1:488e1b7e7341 b "b"
  rebasing 3:a82ac2b38757 c "c"
  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:ef6251596616 f
  |
  o  12:b6f172e64af9 e'
  |
  | o  11:a1707a5b7c2c d
  |/
  o  10:d008e6b4d3fd c
  |
  o  9:67e8f4a16c49 b
  |
  | *  8:2876ce66c6eb g
  | |
  | | 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 12:b6f172e64af9)
  | | |
  | x |  4:76be324c128b d (rewritten using rebase as 11:a1707a5b7c2c)
  | |/
  | x  3:a82ac2b38757 c (rewritten using rebase as 10:d008e6b4d3fd)
  | |
  o |  2:630d7c95eff7 x
  | |
  | x  1:488e1b7e7341 b (rewritten using rebase as 9:67e8f4a16c49)
  |/
  o  0:b173517d0057 a
  

issue5782
  $ hg strip -r 0:
  $ hg debugdrawdag <<EOF
  >       d
  >       |
  >   c1  c # replace: c -> c1
  >    \ /
  >     b
  >     |
  >     a
  > EOF
  1 new orphan changesets
  $ hg debugobsolete `hg log -T "{node}" --hidden -r 'desc("c1")'`
  1 new obsolescence markers
  obsoleted 1 changesets
  $ hg log -G -r 'a': --hidden
  *  4:76be324c128b d
  |
  | x  3:ef8a456de8fa c1 (pruned)
  | |
  x |  2:a82ac2b38757 c (rewritten using replace as 3:ef8a456de8fa)
  |/
  o  1:488e1b7e7341 b
  |
  o  0:b173517d0057 a
  
  $ hg rebase -d 0 -r 2
  note: not rebasing 2:a82ac2b38757 c "c", it has no successor
  $ hg log -G -r 'a': --hidden
  *  4:76be324c128b d
  |
  | x  3:ef8a456de8fa c1 (pruned)
  | |
  x |  2:a82ac2b38757 c (rewritten using replace as 3:ef8a456de8fa)
  |/
  o  1:488e1b7e7341 b
  |
  o  0:b173517d0057 a
  
  $ cd ..

Start a normal rebase. When it runs into conflicts, rewrite one of the
commits in the rebase set, causing divergence when the rebase continues.

  $ hg init $TESTTMP/new-divergence-after-conflict
  $ cd $TESTTMP/new-divergence-after-conflict
  $ hg debugdrawdag <<'EOS'
  >  C2
  >  | C1
  >  |/
  >  B # B/D=B
  >  | D
  >  |/
  >  A
  > EOS
  $ hg rebase -r B::C1 -d D
  rebasing 1:2ec65233581b B "B"
  merging D
  warning: conflicts while merging D! (edit, then use 'hg resolve --mark')
  unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
  [240]
  $ hg debugobsolete $(hg log -r C1 -T '{node}') $(hg log -r C2 -T '{node}')
  1 new obsolescence markers
  obsoleted 1 changesets
  $ hg log -G
  o  4:fdb9df6b130c C2
  |
  | x  3:7e5bfd3c08f0 C1 (rewritten as 4:fdb9df6b130c)
  |/
  | @  2:b18e25de2cf5 D
  | |
  % |  1:2ec65233581b B
  |/
  o  0:426bada5c675 A
  
  $ echo resolved > D
  $ hg resolve -m D
  (no more unresolved files)
  continue: hg rebase --continue
  $ hg rebase -c
  rebasing 1:2ec65233581b B "B"
  note: not rebasing 3:7e5bfd3c08f0 C1 "C1" and its descendants as this would cause divergence
  1 new orphan changesets

Rebase merge where successor of one parent is equal to destination (issue5198)

  $ hg init p1-succ-is-dest
  $ cd p1-succ-is-dest

  $ hg debugdrawdag <<EOF
  >   F
  >  /|
  > E D B # replace: D -> B
  >  \|/
  >   A
  > EOF
  1 new orphan changesets

  $ hg rebase -d B -s D
  note: not rebasing 2:b18e25de2cf5 D "D", already in destination as 1:112478962961 B "B"
  rebasing 4:66f1a38021c9 F tip "F"
  $ hg log -G
  o    5:50e9d60b99c6 F
  |\
  | | x  4:66f1a38021c9 F (rewritten using rebase as 5:50e9d60b99c6)
  | |/|
  | o |  3:7fb047a69f22 E
  | | |
  | | x  2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
  | |/
  o |  1:112478962961 B
  |/
  o  0:426bada5c675 A
  
  $ cd ..

Rebase merge where successor of other parent is equal to destination

  $ hg init p2-succ-is-dest
  $ cd p2-succ-is-dest

  $ hg debugdrawdag <<EOF
  >   F
  >  /|
  > E D B # replace: E -> B
  >  \|/
  >   A
  > EOF
  1 new orphan changesets

  $ hg rebase -d B -s E
  note: not rebasing 3:7fb047a69f22 E "E", already in destination as 1:112478962961 B "B"
  rebasing 4:66f1a38021c9 F tip "F"
  $ hg log -G
  o    5:aae1787dacee F
  |\
  | | x  4:66f1a38021c9 F (rewritten using rebase as 5:aae1787dacee)
  | |/|
  | | x  3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
  | | |
  | o |  2:b18e25de2cf5 D
  | |/
  o /  1:112478962961 B
  |/
  o  0:426bada5c675 A