dirstate: add a `set_tracked` method for "hg add"-like usage
authorPierre-Yves David <pierre-yves.david@octobus.net>
Thu, 08 Jul 2021 03:03:34 +0200
changeset 47593 f927ad5a4e2c
parent 47592 0f5c203eb5ab
child 47594 0cef28b121a4
dirstate: add a `set_tracked` method for "hg add"-like usage This is a step further toward clarifying the semantic of various dirstate call. Having a dedicated function comes with a couple of benefits: 1) we can move duplicated logic about how to handle the previous state within the dirstate. Since we are sure this is always called in the same situation, we can implement that logic once in the dirstate. 2) having a dedicated method for this case unlock also having a dedicated method for the other case and recording more information at that time. All this leading having more code within the dirstate and higher level API that are less error prone. Differential Revision: https://phab.mercurial-scm.org/D11013
hgext/largefiles/lfutil.py
hgext/narrow/narrowdirstate.py
hgext/sparse.py
mercurial/dirstate.py
--- a/hgext/largefiles/lfutil.py	Sat Jul 10 23:31:51 2021 +0200
+++ b/hgext/largefiles/lfutil.py	Thu Jul 08 03:03:34 2021 +0200
@@ -162,6 +162,9 @@
     def __getitem__(self, key):
         return super(largefilesdirstate, self).__getitem__(unixpath(key))
 
+    def set_tracked(self, f):
+        return super(largefilesdirstate, self).set_tracked(unixpath(f))
+
     def normal(self, f):
         return super(largefilesdirstate, self).normal(unixpath(f))
 
--- a/hgext/narrow/narrowdirstate.py	Sat Jul 10 23:31:51 2021 +0200
+++ b/hgext/narrow/narrowdirstate.py	Thu Jul 08 03:03:34 2021 +0200
@@ -38,6 +38,10 @@
             return super(narrowdirstate, self).normal(*args, **kwargs)
 
         @_editfunc
+        def set_tracked(self, *args):
+            return super(narrowdirstate, self).set_tracked(*args)
+
+        @_editfunc
         def add(self, *args):
             return super(narrowdirstate, self).add(*args)
 
--- a/hgext/sparse.py	Sat Jul 10 23:31:51 2021 +0200
+++ b/hgext/sparse.py	Thu Jul 08 03:03:34 2021 +0200
@@ -256,6 +256,7 @@
     # Prevent adding files that are outside the sparse checkout
     editfuncs = [
         b'normal',
+        b'set_tracked',
         b'add',
         b'normallookup',
         b'copy',
--- a/mercurial/dirstate.py	Sat Jul 10 23:31:51 2021 +0200
+++ b/mercurial/dirstate.py	Thu Jul 08 03:03:34 2021 +0200
@@ -83,6 +83,17 @@
     return wrap
 
 
+def requires_no_parents_change(func):
+    def wrap(self, *args, **kwargs):
+        if not self.pendingparentchange():
+            msg = 'calling `%s` inside of a parentchange context'
+            msg %= func.__name__
+            raise error.ProgrammingError(msg)
+        return func(self, *args, **kwargs)
+
+    return wrap
+
+
 @interfaceutil.implementer(intdirstate.idirstate)
 class dirstate(object):
     def __init__(
@@ -451,6 +462,24 @@
     def copies(self):
         return self._map.copymap
 
+    @requires_no_parents_change
+    def set_tracked(self, filename):
+        """a "public" method for generic code to mark a file as tracked
+
+        This function is to be called outside of "update/merge" case. For
+        example by a command like `hg add X`.
+
+        return True the file was previously untracked, False otherwise.
+        """
+        entry = self._map.get(filename)
+        if entry is None:
+            self._add(filename)
+            return True
+        elif not entry.tracked:
+            self.normallookup(filename)
+            return True
+        return False
+
     @requires_parents_change
     def update_file_reference(
         self,