inhibit: fix compat with rebaseskipobsolete
authorLaurent Charignon <lcharignon@fb.com>
Wed, 27 Jan 2016 13:57:08 -0800
changeset 1588 983f2e4dbe5d
parent 1587 ea7523380efa
child 1589 d6630a6bff86
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.
hgext/inhibit.py
tests/test-inhibit.t
--- a/hgext/inhibit.py	Tue Jan 19 15:30:23 2016 -0800
+++ b/hgext/inhibit.py	Wed Jan 27 13:57:08 2016 -0800
@@ -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
--- a/tests/test-inhibit.t	Tue Jan 19 15:30:23 2016 -0800
+++ b/tests/test-inhibit.t	Wed Jan 27 13:57:08 2016 -0800
@@ -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 ..