[Updated] [++-- ] D11364: dirstate-item: keep the full information in memory (for pure form)

marmoute (Pierre-Yves David) phabricator at mercurial-scm.org
Fri Aug 27 17:10:59 UTC 2021


marmoute updated this revision to Diff 30120.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D11364?vs=30119&id=30120

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D11364/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D11364

AFFECTED FILES
  mercurial/pure/parsers.py

CHANGE DETAILS

diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -56,7 +56,17 @@
     - mtime,
     """
 
-    _state = attr.ib()
+    _wc_tracked = attr.ib()
+    _p1_tracked = attr.ib()
+    _p2_tracked = attr.ib()
+    # the three item above should probably be combined
+    #
+    # However it is unclear if they properly cover some of the most advanced
+    # merge case. So we should probably wait on this to be settled.
+    _merged = attr.ib()
+    _clean_p1 = attr.ib()
+    _clean_p2 = attr.ib()
+    _possibly_dirty = attr.ib()
     _mode = attr.ib()
     _size = attr.ib()
     _mtime = attr.ib()
@@ -76,47 +86,21 @@
             msg = b'`merged` argument incompatible with `clean_p1`/`clean_p2`'
             raise error.ProgrammingError(msg)
 
-        self._state = None
-        self._mode = 0
-        self._size = NONNORMAL
-        self._mtime = AMBIGUOUS_TIME
-        if not (p1_tracked or p2_tracked or wc_tracked):
-            pass  # the object has no state to record
-        elif merged:
-            self._state = b'm'
-            self._size = FROM_P2
-            self._mtime = AMBIGUOUS_TIME
-        elif not (p1_tracked or p2_tracked) and wc_tracked:
-            self._state = b'a'
-            self._size = NONNORMAL
-            self._mtime = AMBIGUOUS_TIME
-        elif (p1_tracked or p2_tracked) and not wc_tracked:
-            self._state = b'r'
-            self._size = 0
-            self._mtime = 0
-        elif clean_p2 and wc_tracked:
-            self._state = b'n'
-            self._size = FROM_P2
-            self._mtime = AMBIGUOUS_TIME
-        elif not p1_tracked and p2_tracked and wc_tracked:
-            self._state = b'n'
-            self._size = FROM_P2
-            self._mtime = AMBIGUOUS_TIME
-        elif possibly_dirty:
-            self._state = b'n'
-            self._size = NONNORMAL
-            self._mtime = AMBIGUOUS_TIME
-        elif wc_tracked:
-            # this is a "normal" file
-            if parentfiledata is None:
-                msg = b'failed to pass parentfiledata for a normal file'
-                raise error.ProgrammingError(msg)
-            self._state = b'n'
+        self._wc_tracked = wc_tracked
+        self._p1_tracked = p1_tracked
+        self._p2_tracked = p2_tracked
+        self._merged = merged
+        self._clean_p1 = clean_p1
+        self._clean_p2 = clean_p2
+        self._possibly_dirty = possibly_dirty
+        if parentfiledata is None:
+            self._mode = None
+            self._size = None
+            self._mtime = None
+        else:
             self._mode = parentfiledata[0]
             self._size = parentfiledata[1]
             self._mtime = parentfiledata[2]
-        else:
-            assert False, 'unreachable'
 
     @classmethod
     def new_added(cls):
@@ -125,10 +109,9 @@
         Should eventually be removed
         """
         instance = cls()
-        instance._state = b'a'
-        instance._mode = 0
-        instance._size = NONNORMAL
-        instance._mtime = AMBIGUOUS_TIME
+        instance._wc_tracked = True
+        instance._p1_tracked = False
+        instance._p2_tracked = False
         return instance
 
     @classmethod
@@ -138,10 +121,10 @@
         Should eventually be removed
         """
         instance = cls()
-        instance._state = b'm'
-        instance._mode = 0
-        instance._size = FROM_P2
-        instance._mtime = AMBIGUOUS_TIME
+        instance._wc_tracked = True
+        instance._p1_tracked = True  # might not be True because of rename ?
+        instance._p2_tracked = True  # might not be True because of rename ?
+        instance._merged = True
         return instance
 
     @classmethod
@@ -151,10 +134,10 @@
         Should eventually be removed
         """
         instance = cls()
-        instance._state = b'n'
-        instance._mode = 0
-        instance._size = FROM_P2
-        instance._mtime = AMBIGUOUS_TIME
+        instance._wc_tracked = True
+        instance._p1_tracked = False  # might actually be True
+        instance._p2_tracked = True
+        instance._clean_p2 = True
         return instance
 
     @classmethod
@@ -164,10 +147,9 @@
         Should eventually be removed
         """
         instance = cls()
-        instance._state = b'n'
-        instance._mode = 0
-        instance._size = NONNORMAL
-        instance._mtime = AMBIGUOUS_TIME
+        instance._wc_tracked = True
+        instance._p1_tracked = True
+        instance._possibly_dirty = True
         return instance
 
     @classmethod
@@ -179,7 +161,8 @@
         assert size != FROM_P2
         assert size != NONNORMAL
         instance = cls()
-        instance._state = b'n'
+        instance._wc_tracked = True
+        instance._p1_tracked = True
         instance._mode = mode
         instance._size = size
         instance._mtime = mtime
@@ -192,12 +175,44 @@
         Since the dirstate-v1 format is frozen, the signature of this function
         is not expected to change, unlike the __init__ one.
         """
-        instance = cls()
-        instance._state = state
-        instance._mode = mode
-        instance._size = size
-        instance._mtime = mtime
-        return instance
+        if state == b'm':
+            return cls.new_merged()
+        elif state == b'a':
+            return cls.new_added()
+        elif state == b'r':
+            instance = cls()
+            instance._wc_tracked = False
+            if size == NONNORMAL:
+                instance._merged = True
+                instance._p1_tracked = (
+                    True  # might not be True because of rename ?
+                )
+                instance._p2_tracked = (
+                    True  # might not be True because of rename ?
+                )
+            elif size == FROM_P2:
+                instance._clean_p2 = True
+                instance._p1_tracked = (
+                    False  # We actually don't know (file history)
+                )
+                instance._p2_tracked = True
+            else:
+                instance._p1_tracked = True
+            return instance
+        elif state == b'n':
+            if size == FROM_P2:
+                return cls.new_from_p2()
+            elif size == NONNORMAL:
+                return cls.new_possibly_dirty()
+            elif mtime == AMBIGUOUS_TIME:
+                instance = cls.new_normal(mode, size, 42)
+                instance._mtime = None
+                instance._possibly_dirty = True
+                return instance
+            else:
+                return cls.new_normal(mode, size, mtime)
+        else:
+            raise RuntimeError(b'unknown state: %s' % state)
 
     def set_possibly_dirty(self):
         """Mark a file as "possibly dirty"
@@ -205,7 +220,7 @@
         This means the next status call will have to actually check its content
         to make sure it is correct.
         """
-        self._mtime = AMBIGUOUS_TIME
+        self._possibly_dirty = True
 
     def set_untracked(self):
         """mark a file as untracked in the working copy
@@ -213,15 +228,10 @@
         This will ultimately be called by command like `hg remove`.
         """
         # backup the previous state (useful for merge)
-        size = 0
-        if self.merged:  # merge
-            size = NONNORMAL
-        elif self.from_p2:
-            size = FROM_P2
-        self._state = b'r'
-        self._mode = 0
-        self._size = size
-        self._mtime = 0
+        self._wc_tracked = False
+        self._mode = None
+        self._size = None
+        self._mtime = None
 
     @property
     def mode(self):
@@ -319,19 +329,89 @@
 
     def v1_state(self):
         """return a "state" suitable for v1 serialization"""
-        return self._state
+        if not (self._p1_tracked or self._p2_tracked or self._wc_tracked):
+            # the object has no state to record, this is -currently-
+            # unsupported
+            raise RuntimeError('untracked item')
+        elif not self._wc_tracked:
+            return b'r'
+        elif self._merged:
+            return b'm'
+        elif not (self._p1_tracked or self._p2_tracked) and self._wc_tracked:
+            return b'a'
+        elif self._clean_p2 and self._wc_tracked:
+            return b'n'
+        elif not self._p1_tracked and self._p2_tracked and self._wc_tracked:
+            return b'n'
+        elif self._possibly_dirty:
+            return b'n'
+        elif self._wc_tracked:
+            return b'n'
+        else:
+            raise RuntimeError('unreachable')
 
     def v1_mode(self):
         """return a "mode" suitable for v1 serialization"""
-        return self._mode
+        return self._mode if self._mode is not None else 0
 
     def v1_size(self):
         """return a "size" suitable for v1 serialization"""
-        return self._size
+        if not (self._p1_tracked or self._p2_tracked or self._wc_tracked):
+            # the object has no state to record, this is -currently-
+            # unsupported
+            raise RuntimeError('untracked item')
+        elif not self._wc_tracked:
+            # File was deleted
+            if self._merged:
+                return NONNORMAL
+            elif self._clean_p2:
+                return FROM_P2
+            else:
+                return 0
+        elif self._merged:
+            return FROM_P2
+        elif not (self._p1_tracked or self._p2_tracked) and self._wc_tracked:
+            # Added
+            return NONNORMAL
+        elif self._clean_p2 and self._wc_tracked:
+            return FROM_P2
+        elif not self._p1_tracked and self._p2_tracked and self._wc_tracked:
+            return FROM_P2
+        elif self._possibly_dirty:
+            if self._size is None:
+                return NONNORMAL
+            else:
+                return self._size
+        elif self._wc_tracked:
+            return self._size
+        else:
+            raise RuntimeError('unreachable')
 
     def v1_mtime(self):
         """return a "mtime" suitable for v1 serialization"""
-        return self._mtime
+        if not (self._p1_tracked or self._p2_tracked or self._wc_tracked):
+            # the object has no state to record, this is -currently-
+            # unsupported
+            raise RuntimeError('untracked item')
+        elif not self._wc_tracked:
+            return 0
+        elif self._possibly_dirty:
+            return AMBIGUOUS_TIME
+        elif self._merged:
+            return AMBIGUOUS_TIME
+        elif not (self._p1_tracked or self._p2_tracked) and self._wc_tracked:
+            return AMBIGUOUS_TIME
+        elif self._clean_p2 and self._wc_tracked:
+            return AMBIGUOUS_TIME
+        elif not self._p1_tracked and self._p2_tracked and self._wc_tracked:
+            return AMBIGUOUS_TIME
+        elif self._wc_tracked:
+            if self._mtime is None:
+                return 0
+            else:
+                return self._mtime
+        else:
+            raise RuntimeError('unreachable')
 
     def need_delay(self, now):
         """True if the stored mtime would be ambiguous with the current time"""



To: marmoute, #hg-reviewers
Cc: mercurial-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurial-scm.org/pipermail/mercurial-patches/attachments/20210827/6815179d/attachment-0002.html>


More information about the Mercurial-patches mailing list