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.
--- 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