[PATCH 3 of 3] Resolve issues 1083 and 912 (case collisions between different revisions)

Paul Moore p.f.moore at gmail.com
Tue Apr 22 17:10:56 CDT 2008


# HG changeset patch
# User "Paul Moore <p.f.moore at gmail.com>"
# Date 1208894789 -3600
# Node ID a736b82aff6088cf6dabd53ea1d89415c34aa3b4
# Parent  6e1e2fc3455a242d8ce2ea931b598670723912eb
Resolve issues 1083 and 912 (case collisions between different revisions)

Fixed by ensuring that localrepo.filecommit correctly detects files renamed in
such a way that the names only differ in case. The filecommit function relies
on self.wread(fn) failing with an IO error if the file no longer exists. On
case insensitive systems, this isn't true for case-only name changes. Fixed by
adding an explicit check for the file existing with the specified case.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -679,11 +679,25 @@
         self._wlockref = weakref.ref(l)
         return l
 
+    def check_case(self, fn):
+        """Raise IOError if fn doesn't exist with this exact case"""
+
+        # Check that the file exists in a case sensitive manner - it may be
+        # stored in the filesystem in a different case than the name passed in
+        # (on case insensitive filesystems). To do this, we first check if the
+        # file exists using os.path.exists. If it does, we double check by
+        # ensuring that the case stored in teh filesystem matches the case
+        # supplied in nfn.
+        full_fn = self.wjoin(fn)
+        if not os.path.exists(full_fn) or util.filesystem_case(fn, self.root) != fn:
+            raise IOError(errno.ENOENT, fn)
+
     def filecommit(self, fn, manifest1, manifest2, linkrev, tr, changelist):
         """
         commit an individual file as part of a larger transaction
         """
 
+        self.check_case(fn)
         t = self.wread(fn)
         fl = self.file(fn)
         fp1 = manifest1.get(fn, nullid)


More information about the Mercurial-devel mailing list