Patchwork [4,of,7,mergedriver] filectx: add isabsent method

login
register
mail settings
Submitter Siddharth Agarwal
Date Nov. 16, 2015, 11:46 p.m.
Message ID <7040a88af48337c46394.1447717568@dev666.prn1.facebook.com>
Download mbox | patch
Permalink /patch/11417/
State Accepted
Headers show

Comments

Siddharth Agarwal - Nov. 16, 2015, 11:46 p.m.
# HG changeset patch
# User Siddharth Agarwal <sid0@fb.com>
# Date 1447702047 28800
#      Mon Nov 16 11:27:27 2015 -0800
# Node ID 7040a88af48337c463947171ed16e067ba50ffe9
# Parent  1ac068b89094bece99583ccfe22dae0b7db75a6c
filectx: add isabsent method

This will indicate whether this filectx represents a file that is *not* in a
changectx. This will be used by merge and filemerge code to know about when a
conflict is a change/delete conflict.

While this is kind of hacky, it is the least bad of all the alternatives. Other
options considered but rejected include:
- isinstance(fctx, ...) -- not very Pythonic, doesn't support duck typing
- fctx.size() is None -- the 'size()' call on workingfilectxes causes a disk stat
- fctx.filenode() == nullid -- the semantics around filenode are incredibly
  confusing. In particular, for workingfilectxes, filenode() is always None no
  matter whether the file is present on disk or in either parent. Having different
  behavior for None versus nullid in the merge code is just asking for pain.

Thanks to Pierre-Yves David for early review feedback here.

Patch

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -747,6 +747,13 @@  class basefilectx(object):
     def islink(self):
         return 'l' in self.flags()
 
+    def isabsent(self):
+        """whether this filectx represents a file not in self._changectx
+
+        This is mainly for merge code to detect change/delete conflicts. This is
+        expected to be True for all subclasses of basectx."""
+        return False
+
     _customcmp = False
     def cmp(self, fctx):
         """compare with other file context