merge-actions: add an explicite "no_op" attribute
authorPierre-Yves David <pierre-yves.david@octobus.net>
Fri, 28 Jan 2022 15:19:58 +0100
changeset 48713 5dfaca4464d1
parent 48712 773ad0f5152d
child 48714 c5f05c0d1c8c
merge-actions: add an explicite "no_op" attribute This make the MergeAction smarter and able to describe themself. This is useful to help introducing more MergeAction object that better the complexity of the situation. Differential Revision: https://phab.mercurial-scm.org/D12116
mercurial/merge.py
mercurial/mergestate.py
mercurial/sparse.py
--- a/mercurial/merge.py	Fri Jan 28 19:46:37 2022 +0100
+++ b/mercurial/merge.py	Fri Jan 28 15:19:58 2022 +0100
@@ -527,7 +527,7 @@
             pass
         elif not branchmerge:
             mresult.removefile(f)  # just updating, ignore changes outside clone
-        elif action[0] in mergestatemod.NO_OP_ACTIONS:
+        elif action[0].no_op:
             mresult.removefile(f)  # merge does not affect file
         elif action[0] in nonconflicttypes:
             msg = _(
@@ -699,7 +699,7 @@
                     mergestatemod.ACTION_PATH_CONFLICT_RESOLVE,
                 )
                 and self._actionmapping[a]
-                and a not in mergestatemod.NO_OP_ACTIONS
+                and not a.no_op
             ):
                 return True
 
@@ -1520,7 +1520,8 @@
         # mergestate so that it can be reused on commit
         ms.addcommitinfo(f, op)
 
-    numupdates = mresult.len() - mresult.len(mergestatemod.NO_OP_ACTIONS)
+    num_no_op = mresult.len(mergestatemod.MergeAction.NO_OP_ACTIONS)
+    numupdates = mresult.len() - num_no_op
     progress = repo.ui.makeprogress(
         _(b'updating'), unit=_(b'files'), total=numupdates
     )
@@ -1624,7 +1625,7 @@
         progress.increment(item=f)
 
     # keep (noop, just log it)
-    for a in mergestatemod.NO_OP_ACTIONS:
+    for a in mergestatemod.MergeAction.NO_OP_ACTIONS:
         for f, args, msg in mresult.getactions((a,), sort=True):
             repo.ui.debug(b" %s: %s -> %s\n" % (f, msg, a.__bytes__()))
             # no progress
--- a/mercurial/mergestate.py	Fri Jan 28 19:46:37 2022 +0100
+++ b/mercurial/mergestate.py	Fri Jan 28 15:19:58 2022 +0100
@@ -105,13 +105,19 @@
     Attributes:
 
     _short: internal representation used to identify each action
+
+    no_op:  True if the action does affect the file content or tracking status
     """
 
     ALL_ACTIONS = weakref.WeakSet()
+    NO_OP_ACTIONS = weakref.WeakSet()
 
-    def __init__(self, short):
+    def __init__(self, short, no_op=False):
         self._short = short
         self.ALL_ACTIONS.add(self)
+        self.no_op = no_op
+        if self.no_op:
+            self.NO_OP_ACTIONS.add(self)
 
     def __hash__(self):
         return hash(self._short)
@@ -145,23 +151,17 @@
 ACTION_MERGE = MergeAction(b'm')
 ACTION_LOCAL_DIR_RENAME_GET = MergeAction(b'dg')
 ACTION_DIR_RENAME_MOVE_LOCAL = MergeAction(b'dm')
-ACTION_KEEP = MergeAction(b'k')
+ACTION_KEEP = MergeAction(b'k', no_op=True)
 # the file was absent on local side before merge and we should
 # keep it absent (absent means file not present, it can be a result
 # of file deletion, rename etc.)
-ACTION_KEEP_ABSENT = MergeAction(b'ka')
+ACTION_KEEP_ABSENT = MergeAction(b'ka', no_op=True)
 # the file is absent on the ancestor and remote side of the merge
 # hence this file is new and we should keep it
-ACTION_KEEP_NEW = MergeAction(b'kn')
+ACTION_KEEP_NEW = MergeAction(b'kn', no_op=True)
 ACTION_EXEC = MergeAction(b'e')
 ACTION_CREATED_MERGE = MergeAction(b'cm')
 
-# actions which are no op
-NO_OP_ACTIONS = (
-    ACTION_KEEP,
-    ACTION_KEEP_ABSENT,
-    ACTION_KEEP_NEW,
-)
 
 # Used by concert to detect situation it does not like, not sure what the exact
 # criteria is
--- a/mercurial/sparse.py	Fri Jan 28 19:46:37 2022 +0100
+++ b/mercurial/sparse.py	Fri Jan 28 15:19:58 2022 +0100
@@ -396,7 +396,7 @@
             temporaryfiles.append(file)
             prunedactions[file] = action
         elif branchmerge:
-            if type not in mergestatemod.NO_OP_ACTIONS:
+            if not type.no_op:
                 temporaryfiles.append(file)
                 prunedactions[file] = action
         elif type == mergestatemod.ACTION_FORGET: