mercurial/scmutil.py
changeset 41937 232d4b9d391a
parent 41799 64de5f44eec3
child 41938 ad4a3e2eedb3
--- a/mercurial/scmutil.py	Mon Mar 11 09:20:26 2019 -0700
+++ b/mercurial/scmutil.py	Mon Mar 11 09:42:29 2019 -0700
@@ -28,6 +28,7 @@
 )
 
 from . import (
+    copies as copiesmod,
     encoding,
     error,
     match as matchmod,
@@ -1253,6 +1254,44 @@
         elif not dryrun:
             wctx.copy(origsrc, dst)
 
+def movedirstate(repo, newctx, match=None):
+    """Move the dirstate to newctx and adjust it as necessary."""
+    oldctx = repo['.']
+    ds = repo.dirstate
+    ds.setparents(newctx.node(), nullid)
+    copies = dict(ds.copies())
+    s = newctx.status(oldctx, match=match)
+    for f in s.modified:
+        if ds[f] == 'r':
+            # modified + removed -> removed
+            continue
+        ds.normallookup(f)
+
+    for f in s.added:
+        if ds[f] == 'r':
+            # added + removed -> unknown
+            ds.drop(f)
+        elif ds[f] != 'a':
+            ds.add(f)
+
+    for f in s.removed:
+        if ds[f] == 'a':
+            # removed + added -> normal
+            ds.normallookup(f)
+        elif ds[f] != 'r':
+            ds.remove(f)
+
+    # Merge old parent and old working dir copies
+    oldcopies = copiesmod.pathcopies(newctx, oldctx, match)
+    oldcopies.update(copies)
+    copies = dict((dst, oldcopies.get(src, src))
+                  for dst, src in oldcopies.iteritems())
+    # Adjust the dirstate copies
+    for dst, src in copies.iteritems():
+        if (src not in newctx or dst in newctx or ds[dst] != 'a'):
+            src = None
+        ds.copy(src, dst)
+
 def writerequires(opener, requirements):
     with opener('requires', 'w', atomictemp=True) as fp:
         for r in sorted(requirements):