[PATCH evolve-ext] inhibit: fix compat with rebaseskipobsolete

Laurent Charignon lcharignon at fb.com
Wed Jan 27 21:57:36 UTC 2016


# HG changeset patch
# User Laurent Charignon <lcharignon at fb.com>
# Date 1453931828 28800
#      Wed Jan 27 13:57:08 2016 -0800
# Node ID 154916d0498ee71836ba42b9bd60414001486655
# Parent  91e67ad4cb6c783fa1a32e03359aa6d73c765129
inhibit: fix compat with rebaseskipobsolete

We wrap _computeobsoletenotrebased and _clearrebased to fix the following case:
- Assuming that we have markers from revisions of  the rebase set and
  destination set and that these markers are inhibited
- At the end of the rebase the nodes are still visible because rebase operate
  without inhibition and skip these nodes
Had we not have those markers to begin with the revisions could be hidden at
the end of the rebase.
We keep track in repo._obsoletenotrebased of the obsolete commits skipped by
the rebase and lift the inhibition at the end of the rebase.
We add three test cases to make sure that the edge cases are covered.

diff --git a/hgext/inhibit.py b/hgext/inhibit.py
--- a/hgext/inhibit.py
+++ b/hgext/inhibit.py
@@ -207,6 +207,7 @@
         # obsolete commit to inhibit them
         visibleobsolete = repo.revs('obsolete() - hidden()')
         ignoreset = set(getattr(repo, '_rebaseset', []))
+        ignoreset |= set(getattr(repo, '_obsoletenotrebased', []))
         visibleobsolete = list(r for r in visibleobsolete if r not in ignoreset)
         if visibleobsolete:
             _inhibitmarkers(repo, [repo[r].node() for r in visibleobsolete])
@@ -216,6 +217,28 @@
                                  inhibitposttransaction)
     return transaction
 
+
+# We wrap these two functions to address the following scenario:
+# - Assuming that we have markers between commits in the rebase set and
+#   destination and that these markers are inhibited
+# - At the end of the rebase the nodes are still visible because rebase operate
+#   without inhibition and skip these nodes
+# We keep track in repo._obsoletenotrebased of the obsolete commits skipped by
+# the rebase and lift the inhibition in the end of the rebase.
+
+def _computeobsoletenotrebased(orig, repo, *args, **kwargs):
+    r = orig(repo, *args, **kwargs)
+    repo._obsoletenotrebased = r.keys()
+    return r
+
+def _clearrebased(orig, ui, repo, *args, **kwargs):
+    r = orig(ui, repo, *args, **kwargs)
+    tonode = repo.changelog.node
+    if util.safehasattr(repo, '_obsoletenotrebased'):
+        _deinhibitmarkers(repo, [tonode(k) for k in repo._obsoletenotrebased])
+    return r
+
+
 def extsetup(ui):
     # lets wrap the computation of the obsolete set
     # We apply inhibition there
@@ -262,6 +285,12 @@
                 extensions.wrapfunction(rebase,
                                         '_filterobsoleterevs',
                                         _filterobsoleterevswrap)
+            extensions.wrapfunction(rebase, 'clearrebased', _clearrebased)
+            if util.safehasattr(rebase, '_computeobsoletenotrebased'):
+                extensions.wrapfunction(rebase,
+                                        '_computeobsoletenotrebased',
+                                        _computeobsoletenotrebased)
+
     except KeyError:
         pass
     # There are two ways to save bookmark changes during a transation, we
diff --git a/tests/test-inhibit.t b/tests/test-inhibit.t
--- a/tests/test-inhibit.t
+++ b/tests/test-inhibit.t
@@ -725,8 +725,8 @@
   $ hg rebase -r 15:: -d 21 --config experimental.rebaseskipobsolete=True
   note: not rebasing 15:2d66e189f5b5 "add cM", already in destination as 21:721c3c279519 "add cM"
   rebasing 16:a438c045eb37 "add cN"
-  $ hg up 21
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg up -q 2d66e189f5b5 # To inhibit it as the rest of test depends on it
+  $ hg up -q 21
 
 Directaccess should load after some extensions precised in the conf
 With no extension specified:
@@ -798,6 +798,83 @@
   added 1 changesets with 1 changes to 1 files (+1 heads)
   2 new obsolescence markers
 
+Create a stack (obsolete with successor in dest) -> (not obsolete) and rebase
+it. We expect to not see the stack at the end of the rebase.
+  $ hg log -G  -r "25::"
+  @  25:71eb4f100663 add pk
+  |
+  $ hg up -C 22
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit Dk
+  $ hg prune 22 -s 25
+  1 changesets pruned
+  $ hg rebase -s 22 -d 25 --config experimental.rebaseskipobsolete=True
+  note: not rebasing 22:46cb6daad392 "add cN", already in destination as 25:71eb4f100663 "add pk"
+  rebasing 26:7ad60e760c7b "add Dk" (tip)
+  $ hg log -G  -r "25::"
+  @  27:1192fa9fbc68 add Dk
+  |
+  o  25:71eb4f100663 add pk
+  |
+
+Create a stack (obsolete with succ in dest) -> (not obsolete) -> (not obsolete).
+Rebase the first two revs of the stack onto dest, we expect to see one new
+revision on the destination and everything visible.
+  $ hg up 25
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit Dl
+  created new head
+  $ mkcommit Dp
+  $ mkcommit Do
+  $ hg log -G -r "25::"
+  @  30:b517facce1ef add Do
+  |
+  o  29:c5a47ab27c2e add Dp
+  |
+  o  28:8c1c2edbaf1b add Dl
+  |
+  | o  27:1192fa9fbc68 add Dk
+  |/
+  o  25:71eb4f100663 add pk
+  |
+  $ hg prune 28 -s 27
+  1 changesets pruned
+  $ hg up 25
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  $ hg rebase -r "28 + 29" --keep -d 27 --config experimental.rebaseskipobsolete=True
+  note: not rebasing 28:8c1c2edbaf1b "add Dl", already in destination as 27:1192fa9fbc68 "add Dk"
+  rebasing 29:c5a47ab27c2e "add Dp"
+  $ hg log -G  -r "25::"
+  o  31:7d8affb1f604 add Dp
+  |
+  | o  30:b517facce1ef add Do
+  | |
+  | o  29:c5a47ab27c2e add Dp
+  | |
+  | o  28:8c1c2edbaf1b add Dl
+  | |
+  o |  27:1192fa9fbc68 add Dk
+  |/
+  @  25:71eb4f100663 add pk
+  |
+
+Rebase the same stack in full on the destination, we expect it to disappear
+and only see the top revision added to destination. We don\'t expect 29 to be
+skipped as we used --keep before.
+  $ hg rebase -s 28 -d 27 --config experimental.rebaseskipobsolete=True
+  note: not rebasing 28:8c1c2edbaf1b "add Dl", already in destination as 27:1192fa9fbc68 "add Dk"
+  rebasing 29:c5a47ab27c2e "add Dp"
+  rebasing 30:b517facce1ef "add Do"
+  $ hg log -G  -r "25::"
+  o  32:1d43fff9e26f add Do
+  |
+  o  31:7d8affb1f604 add Dp
+  |
+  o  27:1192fa9fbc68 add Dk
+  |
+  @  25:71eb4f100663 add pk
+  |
+
 Pulling from a inhibit repo to a non-inhibit repo should work
 
   $ cd ..


More information about the Mercurial-devel mailing list