comparison mercurial/context.py @ 34835:14c87708f432

arbitraryfilecontext: skip the cmp fast path if any side is a symlink `filecmp` follows symlinks by default, which a `filectx.cmp()` call should not be doing as it should only compare the requested entry. After this patch, only the contexts' data are compared, which is the correct contract. This is a corrected version of D1122. Differential Revision: https://phab.mercurial-scm.org/D1165
author Phil Cohen <phillco@fb.com>
date Tue, 17 Oct 2017 12:41:24 -0700
parents 07bbb208a924
children f7e4d6c20095
comparison
equal deleted inserted replaced
34834:2e8477059d4f 34835:14c87708f432
2568 # Repo is optional because contrib/simplemerge uses this class. 2568 # Repo is optional because contrib/simplemerge uses this class.
2569 self._repo = repo 2569 self._repo = repo
2570 self._path = path 2570 self._path = path
2571 2571
2572 def cmp(self, fctx): 2572 def cmp(self, fctx):
2573 if isinstance(fctx, workingfilectx) and self._repo: 2573 # filecmp follows symlinks whereas `cmp` should not, so skip the fast
2574 # path if either side is a symlink.
2575 symlinks = ('l' in self.flags() or 'l' in fctx.flags())
2576 if not symlinks and isinstance(fctx, workingfilectx) and self._repo:
2574 # Add a fast-path for merge if both sides are disk-backed. 2577 # Add a fast-path for merge if both sides are disk-backed.
2575 # Note that filecmp uses the opposite return values as cmp. 2578 # Note that filecmp uses the opposite return values (True if same)
2579 # from our cmp functions (True if different).
2576 return not filecmp.cmp(self.path(), self._repo.wjoin(fctx.path())) 2580 return not filecmp.cmp(self.path(), self._repo.wjoin(fctx.path()))
2577 return self.data() != fctx.data() 2581 return self.data() != fctx.data()
2578 2582
2579 def path(self): 2583 def path(self):
2580 return self._path 2584 return self._path