Patchwork [5,of,5] scmutil: check collision between directory part of added file and tracked ones

login
register
mail settings
Submitter Katsunori FUJIWARA
Date Nov. 11, 2013, 3:16 p.m.
Message ID <d427725dfe46a907480c.1384182960@juju>
Download mbox | patch
Permalink /patch/2904/
State Superseded
Headers show

Comments

Katsunori FUJIWARA - Nov. 11, 2013, 3:16 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1384182518 -32400
#      Tue Nov 12 00:08:38 2013 +0900
# Node ID d427725dfe46a907480c9d37cfa4fb0ded95c64e
# Parent  f3dbb1f34b4fa0ee743c7a43a95e3c4c92ad3099
scmutil: check collision between directory part of added file and tracked ones

Before this patch, "hg add" doesn't show any warning messages, when
directory part of newly added file causes case-folding collision
against directory part of already tracked ones.

Such adding causes that "hg update" stores files belonging to
different directories in the manifest into same directory in the
working directory unexpectedly on icasefs system.

This patch checks case-folding collision between directory part of
newly added file and already tracked ones.

This patch tests collision detection by multiple path patterns
corresponded to detections in the first, the middle and the last of
"while dparts" loop.

To prevent regression, this patch tests also that collision between
directory part of newly added file and already removed one is ignored.

Patch

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -111,6 +111,7 @@ 
             self._ui.warn(_("warning: %s\n") % msg)
         else:
             dirstate = self._dirstate
+            dirstatedirs = dirstate.dirs()
             dparts = f.split('/')
             dparts.pop()
             dlparts = fl.split('/')
@@ -126,6 +127,12 @@ 
                         raise util.Abort(msg)
                     self._ui.warn(_("warning: %s\n") % msg)
                     break
+                elif dl in self._lowereddirs and d not in dirstatedirs:
+                    msg = _('possible case-folding collision for %s') % f
+                    if self._abort:
+                        raise util.Abort(msg)
+                    self._ui.warn(_("warning: %s\n") % msg)
+                    break
                 dparts.pop()
         self._loweredfiles.add(fl)
         self._newfiles.add(f)
diff --git a/tests/test-casecollision.t b/tests/test-casecollision.t
--- a/tests/test-casecollision.t
+++ b/tests/test-casecollision.t
@@ -81,6 +81,16 @@ 
   $ hg add J/J4 J/j4
   warning: possible case-folding collision for J/j4
 
+  $ mkdir -p K/K/K1 K/K2 K3 K/K/k1 K/k2/K k3/K/K
+  $ touch K/K/K1/x K/K2/x K3/x K/K/k1/y K/k2/K/y k3/K/K/y
+  $ hg add K/K/K1/x K/K2/x K3/x K/K/k1/y K/k2/K/y k3/K/K/y
+  warning: possible case-folding collision for K/K/k1/y
+  warning: possible case-folding collision for K/k2/K/y
+  warning: possible case-folding collision for k3/K/K/y
+  $ mkdir K/K/K4
+  $ touch K/K/K4/x
+  $ hg add K/K/K4/x
+
   $ hg commit -m '#0'
 
   $ hg remove I/I2/x
@@ -93,6 +103,11 @@ 
   $ hg add J/j4/y
   warning: possible case-folding collision for J/j4/y
 
+  $ hg remove K/K/K4/x
+  $ mkdir K/K/k4
+  $ touch K/K/k4/y
+  $ hg add K/K/k4/y
+
 case changing rename must not warn or abort
 
   $ echo c > c