evolve: use repo.setparents() instead of repo.dirstate.setparents() draft stable
authorAnton Shestakov <av6@dwimlabs.net>
Sun, 26 Jan 2020 20:57:39 +0700
branchstable
changeset 5246 814083e5f7e8
parent 5095 2fcaee044a8c
child 5247 5a2e7c6f9174
evolve: use repo.setparents() instead of repo.dirstate.setparents() setparents() was added to localrepository class in 2012, and now we finally have some differences between calling repo.setparents() vs repo.dirstate.setparents(): _quick_access_* things, introduced in hg 5.3. This patch fixes an actual quick-access desync problem where repo[b'.'] would be different from repo.dirstate.p1(), as demonstrated by test-evolve-phase-divergence.t when ran on hg 5.3rc0 and later. Modified _uncommitdirstate() too, because it is used in dirstatedance(), which sometimes follows repo.setparents() calls.
hgext3rd/evolve/cmdrewrite.py
hgext3rd/evolve/evolvecmd.py
--- a/hgext3rd/evolve/cmdrewrite.py	Fri Jan 17 20:40:24 2020 +0700
+++ b/hgext3rd/evolve/cmdrewrite.py	Sun Jan 26 20:57:39 2020 +0700
@@ -450,6 +450,11 @@
             src = None
         ds.copy(src, dst)
 
+    # After doing low-level modifications to dirstate, we have to also do this
+    # hg <= 5.2 (85c4cd73996b)
+    if util.safehasattr(repo, '_quick_access_changeid_invalidate'):
+        repo._quick_access_changeid_invalidate()
+
 @eh.command(
     b'uncommit',
     [(b'a', b'all', None, _(b'uncommit all changes when no arguments given')),
--- a/hgext3rd/evolve/evolvecmd.py	Fri Jan 17 20:40:24 2020 +0700
+++ b/hgext3rd/evolve/evolvecmd.py	Sun Jan 26 20:57:39 2020 +0700
@@ -297,7 +297,7 @@
     bmupdate(newid)
     # reroute the working copy parent to the new changeset
     with repo.dirstate.parentchange():
-        repo.dirstate.setparents(newid, nodemod.nullid)
+        repo.setparents(newid, nodemod.nullid)
     return (True, replacementnode)
 
 def _solvedivergent(ui, repo, divergent, evolvestate, displayer, dryrun=False,
@@ -624,7 +624,7 @@
         otherdiv = repo[othernode]
 
         with repo.dirstate.parentchange():
-            repo.dirstate.setparents(publicnode, nodemod.nullid)
+            repo.setparents(publicnode, nodemod.nullid)
             dirstatedance(repo, divergent, publicnode, None)
         # check if node to be committed has changes same as public one
         s = publicdiv.status()
@@ -637,7 +637,7 @@
             return (True, publicnode)
     try:
         with repo.dirstate.parentchange():
-            repo.dirstate.setparents(resparent, nodemod.nullid)
+            repo.setparents(resparent, nodemod.nullid)
 
         dirstatedance(repo, divergent, resparent, None)
 
@@ -784,7 +784,7 @@
 def dirstatedance(repo, oldparent, newparent, match):
     """utility function to fix the dirstate when we change parents from
     oldparent to newparent with a dirty working directory using
-    repo.dirstate.setparents()
+    repo.setparents()
 
     Lets refer oldparent as Pold
                newparent as Pnew
@@ -2151,27 +2151,24 @@
             # directory parent should be successor of p1, so we should
             # set dirstate parents to (succ of p1, p2)
             with repo.dirstate.parentchange():
-                repo.dirstate.setparents(currentp1,
-                                         ctxparents[1].node())
+                repo.setparents(currentp1, ctxparents[1].node())
         elif p2obs and not p1obs:
             # p2 is obsolete and p1 is not obsolete, current working
             # directory parent should be successor of p2, so we should
             # set dirstate parents to (succ of p2, p1)
             with repo.dirstate.parentchange():
-                repo.dirstate.setparents(ctxparents[0].node(),
-                                         currentp1)
+                repo.setparents(ctxparents[0].node(), currentp1)
 
         else:
             # both the parents were obsoleted, if orphanmerge is set, we
             # are processing the second parent first (to keep parent order)
             if evolvestate.get(b'orphanmerge'):
                 with repo.dirstate.parentchange():
-                    repo.dirstate.setparents(ctxparents[0].node(),
-                                             currentp1)
+                    repo.setparents(ctxparents[0].node(), currentp1)
             pass
     else:
         with repo.dirstate.parentchange():
-            repo.dirstate.setparents(repo.dirstate.parents()[0], nodemod.nullid)
+            repo.setparents(repo.dirstate.parents()[0], nodemod.nullid)
 
     with repo.ui.configoverride(overrides, b'evolve-continue'):
         node = repo.commit(text=message, user=user,