evolve: introduce a dirstatedance() fn to fix dirstate after parent change
authorPulkit Goyal <7895pulkit@gmail.com>
Wed, 13 Jun 2018 18:08:57 +0530
changeset 3847 8bad32e1e6c1
parent 3846 f9dad99a90d5
child 3848 90f1a64875ad
evolve: introduce a dirstatedance() fn to fix dirstate after parent change This patch introduces a dirstatedance() function which will be used after fixing the dirstate when we change parents using repo.dirstate.setparents(). Look at docs added for more details.
hgext3rd/evolve/evolvecmd.py
--- a/hgext3rd/evolve/evolvecmd.py	Wed Jun 13 17:15:10 2018 +0530
+++ b/hgext3rd/evolve/evolvecmd.py	Wed Jun 13 18:08:57 2018 +0530
@@ -518,7 +518,7 @@
         with repo.dirstate.parentchange():
             repo.dirstate.setparents(divergent.p1().node(), node.nullid)
 
-        cmdrewrite._uncommitdirstate(repo, divergent, None, True)
+        dirstatedance(repo, divergent, divergent.p1(), None)
 
         # merge the branches
         mergebranches(repo, divergent, other, base)
@@ -569,6 +569,73 @@
     finally:
         repo.ui.restoreconfig(emtpycommitallowed)
 
+def dirstatedance(repo, oldparent, newparent, match):
+    """utility function to fix the dirstate when we change parents from
+    oldparent to newparent with a directory working directory using
+    repo.dirstate.setparents()
+
+    Lets refer oldparent as Pold
+               newparent as Pnew
+
+    Now when we are on oldparent with a dirty working directory, there are three
+    types of files which we are concerned about. They are files having modified,
+    added and removed status.
+
+    Lets refer modified files as Fm
+               added files as Fa
+               removed files as Fr
+
+    Now, between Pold and Pnew, files can be modified, files can be added, files
+    can be removed.
+
+    Lets refer modification of a file between Pold to Pnew as Cm
+               addition of a file between Pold to Pnew as Ca
+               removal of a file between Pold to Pnew as Cr
+
+    Now let's play combinations and permutations:
+
+    |---------------------------------------------------------------|
+    | Type of file |  Changes between |   End status with Pnew as   |
+    |   in wdir    |    Pold -> Pnew  |       wdir parent           |
+    |--------------|------------------|-----------------------------|
+    |              |                  |                             |
+    |   Fm         |      Cm          |       Modified or clean     |
+    |--------------|------------------|-----------------------------|
+    |   Fm         |      Cr          |           Added             |
+    |--------------|------------------|-----------------------------|
+    |   Fm         |      Ca          |       Not possible (1)      |
+    |--------------|------------------|-----------------------------|
+    |   Fa         |      Ca          |       Modified or clean     |
+    |--------------|------------------|-----------------------------|
+    |   Fa         |      Cm          |       Not possible (2)      |
+    |--------------|------------------|-----------------------------|
+    |   Fa         |      Cr          |       Not possible (2)      |
+    |--------------|------------------|-----------------------------|
+    |   Fr         |      Cr          | File should be untracked (3)|
+    |--------------|------------------|-----------------------------|
+    |   Fr         |      Ca          |       Not possible (4)      |
+    |--------------|------------------|-----------------------------|
+    |   Fr         |      Cm          |           Removed           |
+    |--------------|------------------|-----------------------------|
+
+    (1): File is modified in wdir, it means file was present in Pold, so
+         addition of that file between Pold to Pnew is not possible
+
+    (2): File was added in wdir, it means file was not present in Pold, so
+         deletion or modification of that file from Pold to Pnew is not possible
+
+    (3): File should be dropped from the dirstate, Pnew has it removed, so no
+         need to mark that removed again
+
+    (4): File was removed in wdir, it means file was present in Pold, so
+         addition of that file between Pold to Pnew is not possible
+
+    """
+
+    # falling back to an existing function, in future we should have logic in
+    # this function only
+    cmdrewrite._uncommitdirstate(repo, oldparent, match, True)
+
 def mergebranches(repo, divergent, other, base):
     """merges the branch information for content-divergent changesets and sets
     the dirstate branch accordingly