[PATCH RFC] repo: add an ability to hide nodes in an appropriate way

Kostia Balytskyi ikostia at fb.com
Sun Mar 26 22:32:55 UTC 2017


# HG changeset patch
# User Kostia Balytskyi <ikostia at fb.com>
# Date 1490567500 25200
#      Sun Mar 26 15:31:40 2017 -0700
# Node ID 43cd56f38c1ca2ad1920ed6804e1a90a5e263c0d
# Parent  c60091fa1426892552dd6c0dd4b9c49e3c3da045
repo: add an ability to hide nodes in an appropriate way

Potentially frequent usecase is to hide nodes in the most appropriate
for current repo configuration way. Examples of things which use this
are rebase (strip or obsolete old nodes), shelve (strip of obsolete
temporary nodes) and probably others.
Jun Wu had an idea of having one place in core where this functionality
is implemented so that others can utilize it. This patch
implements this idea.

'insistonstripping' is necessary for cases when caller might need
to enforce or not enforce stripping depending on some configuration
(like shelve needs now).

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -50,6 +50,7 @@ from . import (
     phases,
     pushkey,
     pycompat,
+    repair,
     repoview,
     revset,
     revsetlang,
@@ -1884,6 +1885,23 @@ class localrepository(object):
         # tag cache retrieval" case to work.
         self.invalidate()
 
+    def hidenodes(self, nodes, insistonstripping=False):
+        '''Remove nodes from visible repoview in the most appropriate
+        supported way. When obsmarker creation is enabled, this
+        function will obsolete these nodes without successors
+        (unless insistonstripping is True). Otherwise, it will
+        strip nodes.
+
+        In future we can add other node-hiding capabilities to this
+        function.'''
+        with self.lock():
+            if obsolete.isenabled(self, obsolete.createmarkersopt)\
+               and not insistonstripping:
+                relations = [(self[n], ()) for n in nodes]
+                obsolete.createmarkers(self, relations)
+            else:
+                repair.strip(self.ui, self, nodes, backup=False)
+
     def walk(self, match, node=None):
         '''
         walk recursively through the directory tree or a given
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -1259,3 +1259,43 @@ Test the --delete option of debugobsolet
   1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 \(.*\) {'user': 'test'} (re)
   $ cd ..
 
+Test that repo.hidenodes respects obsolescense configs
+  $ hg init hidenodesrepo && cd hidenodesrepo
+  $ cat <<EOF > debughidenodes.py
+  > from __future__ import absolute_import
+  > from mercurial import (
+  >     cmdutil,
+  > )
+  > cmdtable = {}
+  > command = cmdutil.command(cmdtable)
+  > @command('debughidenodes',
+  >         [('', 'insiststrip', None, 'pass insistonstripping=True')])
+  > def debughidenodes(ui, repo, *args, **opts):
+  >     nodes = [repo[n].node() for n in args]
+  >     repo.hidenodes(nodes, insistonstripping=bool(opts.get('insiststrip')))
+  > EOF
+  $ cat <<EOF > .hg/hgrc
+  > [extensions]
+  > debughidenodes=debughidenodes.py
+  > EOF
+  $ echo a > a
+  $ hg add a && hg ci -m a && hg up null
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg --config experimental.evolution=! debughidenodes 0
+  $ hg log -qr "all()" --hidden | wc -l  # commit was actually stripped
+  \s*0 (re)
+  $ hg debugobsolete | wc -l  # no markers were created
+  \s*0 (re)
+  $ echo a > a && hg add a && hg ci -m a && hg up null
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg --config experimental.evolution=createmarkers debughidenodes 0
+  $ hg log -qr "all()" --hidden | wc -l  # commit was not stripped
+  \s*1 (re)
+  $ hg debugobsolete | wc -l  # a marker was created
+  \s*1 (re)
+  $ hg --config experimental.evolution=createmarkers --hidden debughidenodes 0 --insiststrip
+  $ hg log -qr "all()" --hidden | wc -l  # commit was actually stripped
+  \s*0 (re)
+  $ hg debugobsolete | wc -l  # no new markers were created
+  \s*1 (re)
+  $ cd ..


More information about the Mercurial-devel mailing list