diff --git a/mercurial/mergestate.py b/mercurial/mergestate.py
--- a/mercurial/mergestate.py
+++ b/mercurial/mergestate.py
@@ -743,34 +743,34 @@
     # remove (must come first)
     for f, args, msg in actions.get(ACTION_REMOVE, []):
         if branchmerge:
-            repo.dirstate.remove(f)
+            repo.dirstate.update_file(f, p1_tracked=True, wc_tracked=False)
         else:
-            repo.dirstate.drop(f)
+            repo.dirstate.update_file(f, p1_tracked=False, wc_tracked=False)
 
     # forget (must come first)
     for f, args, msg in actions.get(ACTION_FORGET, []):
-        repo.dirstate.drop(f)
+        repo.dirstate.update_file(f, p1_tracked=False, wc_tracked=False)
 
     # resolve path conflicts
     for f, args, msg in actions.get(ACTION_PATH_CONFLICT_RESOLVE, []):
         (f0, origf0) = args
-        repo.dirstate.add(f)
+        repo.dirstate.update_file(f, p1_tracked=False, wc_tracked=True)
         repo.dirstate.copy(origf0, f)
         if f0 == origf0:
-            repo.dirstate.remove(f0)
+            repo.dirstate.update_file(f0, p1_tracked=True, wc_tracked=False)
         else:
-            repo.dirstate.drop(f0)
+            repo.dirstate.update_file(f0, p1_tracked=False, wc_tracked=False)
 
     # re-add
     for f, args, msg in actions.get(ACTION_ADD, []):
-        repo.dirstate.add(f)
+        repo.dirstate.update_file(f, p1_tracked=False, wc_tracked=True)
 
     # re-add/mark as modified
     for f, args, msg in actions.get(ACTION_ADD_MODIFIED, []):
         if branchmerge:
             repo.dirstate.normallookup(f)
         else:
-            repo.dirstate.add(f)
+            repo.dirstate.update_file(f, p1_tracked=False, wc_tracked=True)
 
     # exec change
     for f, args, msg in actions.get(ACTION_EXEC, []):
@@ -791,10 +791,17 @@
     # get
     for f, args, msg in actions.get(ACTION_GET, []):
         if branchmerge:
-            repo.dirstate.otherparent(f)
+            # tracked in p1 can be True also but update_file should not care
+            repo.dirstate.update_file(
+                f,
+                p1_tracked=False,
+                p2_tracked=True,
+                wc_tracked=True,
+                clean_p2=True,
+            )
         else:
             parentfiledata = getfiledata[f] if getfiledata else None
-            repo.dirstate.normal(f, parentfiledata=parentfiledata)
+            repo.dirstate.update_parent_file_data(f, parentfiledata)
 
     # merge
     for f, args, msg in actions.get(ACTION_MERGE, []):
@@ -802,10 +809,14 @@
         if branchmerge:
             # We've done a branch merge, mark this file as merged
             # so that we properly record the merger later
-            repo.dirstate.merge(f)
+            repo.dirstate.update_file(
+                f, p1_tracked=True, wc_tracked=True, merged=True
+            )
             if f1 != f2:  # copy/rename
                 if move:
-                    repo.dirstate.remove(f1)
+                    repo.dirstate.update_file(
+                        f1, p1_tracked=True, wc_tracked=False
+                    )
                 if f1 != f:
                     repo.dirstate.copy(f1, f)
                 else:
@@ -817,26 +828,30 @@
             # merge will appear as a normal local file
             # modification.
             if f2 == f:  # file not locally copied/moved
-                repo.dirstate.normallookup(f)
+                repo.dirstate.update_file(
+                    f, p1_tracked=True, wc_tracked=True, possibly_dirty=True
+                )
             if move:
-                repo.dirstate.drop(f1)
+                repo.dirstate.update_file(
+                    f1, p1_tracked=False, wc_tracked=False
+                )
 
     # directory rename, move local
     for f, args, msg in actions.get(ACTION_DIR_RENAME_MOVE_LOCAL, []):
         f0, flag = args
         if branchmerge:
-            repo.dirstate.add(f)
-            repo.dirstate.remove(f0)
+            repo.dirstate.update_file(f, p1_tracked=False, wc_tracked=True)
+            repo.dirstate.update_file(f0, p1_tracked=True, wc_tracked=False)
             repo.dirstate.copy(f0, f)
         else:
-            repo.dirstate.normal(f)
-            repo.dirstate.drop(f0)
+            repo.dirstate.update_file(f, p1_tracked=True, wc_tracked=True)
+            repo.dirstate.update_file(f0, p1_tracked=False, wc_tracked=False)
 
     # directory rename, get
     for f, args, msg in actions.get(ACTION_LOCAL_DIR_RENAME_GET, []):
         f0, flag = args
         if branchmerge:
-            repo.dirstate.add(f)
+            repo.dirstate.update_file(f, p1_tracked=False, wc_tracked=True)
             repo.dirstate.copy(f0, f)
         else:
-            repo.dirstate.normal(f)
+            repo.dirstate.update_file(f, p1_tracked=True, wc_tracked=True)