filemerge: convert a couple of wvfs calls in internal mergetools to contexts
authorPhil Cohen <phillco@fb.com>
Mon, 26 Jun 2017 22:52:15 -0700
changeset 33151 851825214aa3
parent 33150 77e666f943a6
child 33152 367a3c6473d2
filemerge: convert a couple of wvfs calls in internal mergetools to contexts One hitch is that sometimes fcd is actually an absentfilectx which does not expose any mutator functions. In order to still use the context functions, we look up the underlying workingfilectx to perform the write there. One alternate way would be to put the write functions on the absentfilectx and have them pass-through. While this makes the callsites cleaner, we would need to decide what its getter functions would return after this point, since returning None for `data` (and True for `isabsent()`) might no longer be correct after a write. I discussed with Sidd about just having the getters raise RuntimeErrors after a mutator has been called, but we actually call isabsent() in merge.py after running the internal merge tools.
mercurial/filemerge.py
--- a/mercurial/filemerge.py	Wed Jun 28 13:50:20 2017 +0200
+++ b/mercurial/filemerge.py	Mon Jun 26 22:52:15 2017 -0700
@@ -298,10 +298,10 @@
     """Uses the other `p2()` version of files as the merged version."""
     if fco.isabsent():
         # local changed, remote deleted -- 'deleted' picked
-        repo.wvfs.unlinkpath(fcd.path())
+        _underlyingfctxifabsent(fcd).remove()
         deleted = True
     else:
-        repo.wwrite(fcd.path(), fco.data(), fco.flags())
+        _underlyingfctxifabsent(fcd).write(fco.data(), fco.flags())
         deleted = False
     return 0, deleted
 
@@ -313,9 +313,19 @@
     used to resolve these conflicts."""
     # for change/delete conflicts write out the changed version, then fail
     if fcd.isabsent():
-        repo.wwrite(fcd.path(), fco.data(), fco.flags())
+        _underlyingfctxifabsent(fcd).write(fco.data(), fco.flags())
     return 1, False
 
+def _underlyingfctxifabsent(filectx):
+    """Sometimes when resolving, our fcd is actually an absentfilectx, but
+    we want to write to it (to do the resolve). This helper returns the
+    underyling workingfilectx in that case.
+    """
+    if filectx.isabsent():
+        return filectx.changectx()[filectx.path()]
+    else:
+        return filectx
+
 def _premerge(repo, fcd, fco, fca, toolconf, files, labels=None):
     tool, toolpath, binary, symlink = toolconf
     if symlink or fcd.isabsent() or fco.isabsent():