[PATCH] dirstate: don't require exact case when adding dirs on icasefs (issue4578)

Matt Harbison mharbison at attotech.com
Tue Mar 31 17:53:06 UTC 2015


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1427814699 14400
#      Tue Mar 31 11:11:39 2015 -0400
# Node ID c92f9acf447de31a6fe51ac664c26c42032117fd
# Parent  888dcab69ca3fe817786a7078bb1f66afa203c8b
dirstate: don't require exact case when adding dirs on icasefs (issue4578)

We don't require it when adding files on a case insensitive filesystem, so don't
require it to add directories for consistency.

The problem with the previous code was that _walkexplicit() was only returning
the normalized directory.  The file(s) in the directory are then appended, and
passed to the matcher.  But if the user asks for 'capsdir1/capsdir', the matcher
will not accept 'CapsDir1/CapsDir/AbC.txt', and the name is dropped.  Matching
based on the non-normalized name is required.

If not normalizing, skip the extra string building for efficiency.  '.' is
replaced with '' so that the path being tested when no file is specified, isn't
prefixed with './' (and therefore fail the match).

diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -652,7 +652,7 @@ class dirstate(object):
                         results[nf] = None
                     if matchedir:
                         matchedir(nf)
-                    foundadd(nf)
+                    foundadd((nf, ff))
                 elif kind == regkind or kind == lnkkind:
                     results[nf] = st
                 else:
@@ -728,15 +728,16 @@ class dirstate(object):
         results, work, dirsnotfound = self._walkexplicit(match, subrepos)
 
         skipstep3 = skipstep3 and not (work or dirsnotfound)
-        work = [d for d in work if not dirignore(d)]
+        work = [d for d in work if not dirignore(d[0])]
         wadd = work.append
 
         # step 2: visit subdirectories
         while work:
-            nd = work.pop()
+            nd, d = work.pop()
             skip = None
             if nd == '.':
                 nd = ''
+                d = ''
             else:
                 skip = '.hg'
             try:
@@ -749,21 +750,23 @@ class dirstate(object):
             for f, kind, st in entries:
                 if normalize:
                     nf = normalize(nd and (nd + "/" + f) or f, True, True)
+                    f = d and (d + "/" + f) or f
                 else:
                     nf = nd and (nd + "/" + f) or f
+                    f = nf
                 if nf not in results:
                     if kind == dirkind:
                         if not ignore(nf):
                             if matchtdir:
                                 matchtdir(nf)
-                            wadd(nf)
+                            wadd((nf, f))
                         if nf in dmap and (matchalways or matchfn(nf)):
                             results[nf] = None
                     elif kind == regkind or kind == lnkkind:
                         if nf in dmap:
                             if matchalways or matchfn(nf):
                                 results[nf] = st
-                        elif (matchalways or matchfn(nf)) and not ignore(nf):
+                        elif (matchalways or matchfn(f)) and not ignore(nf):
                             results[nf] = st
                     elif nf in dmap and (matchalways or matchfn(nf)):
                         results[nf] = None
diff --git a/tests/test-add.t b/tests/test-add.t
--- a/tests/test-add.t
+++ b/tests/test-add.t
@@ -169,4 +169,16 @@ forgotten before file with same name is 
   $ cat d
   file d
 
+Test that adding a directory doesn't require case matching (issue4578)
+#if icasefs
+  $ mkdir -p CapsDir1/CapsDir
+  $ echo abc > CapsDir1/CapsDir/AbC.txt
+  $ mkdir CapsDir1/CapsDir/SubDir
+  $ echo def > CapsDir1/CapsDir/SubDir/Def.txt
+
+  $ hg add -v capsdir1/capsdir
+  adding CapsDir1/CapsDir/AbC.txt (glob)
+  adding CapsDir1/CapsDir/SubDir/Def.txt (glob)
+#endif
+
   $ cd ..


More information about the Mercurial-devel mailing list