Most case-insensitive filesystems are case-preserving. In these
filesystems (such as HFS+ on OS X) you can name a file Filename.txt,
then rename the file to FileName.txt.  That file will be accessible
by both filenames, but the case is otherwise honored.  We don't want
to have git ignore case on these case-preserving filesystem
implementations.

This change adds an additional check in init-db.c before
automatically setting core.ignorecase to true.

This fixes a problem where if you import an hg repository, using
git-remote-hg, on two OSX systems, one with a case-sensitive fs and
the other with case-insensitive fs, the sha1 commit ids of the
repositories diverge on commits where a file was renamed, but only
the case in the filename changes (for example renaming
Filename.cpp -> FileName.cpp).

The alternative solutions are
* to set ignore_case to 0 in fast-import.c at runtime
* explicitly use strcmp, rather than strcmp_icase (also in
  fast-import.c)
* completely rework ignorecase into something that can handle more
  options (true, false, sometimes, maybe, partially, etc...)

Signed-off-by: Reuben Hawkins <reuben...@gmail.com>
---
 builtin/init-db.c |   43 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/builtin/init-db.c b/builtin/init-db.c
index 78aa387..34f09d8 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -288,8 +288,47 @@ static int create_default_files(const char *template_path)
                /* Check if the filesystem is case-insensitive */
                path[len] = 0;
                strcpy(path + len, "CoNfIg");
-               if (!access(path, F_OK))
-                       git_config_set("core.ignorecase", "true");
+               if (!access(path, F_OK)) {
+                       /*
+                        * This filesystem is at least partially 
case-insensitive.  Let's
+                        * find out if this filesystem is completely 
case-insensitive.
+                        *
+                        * Create a CamelCase file here, make sure readdir 
reads a
+                        * CamelCase file below.
+                        */
+                       int completely_insensitive_fs = 1;
+                       char const * const case_check_filename = ".CaseCheck";
+                       struct dirent *dirent;
+                       FILE *case_file;
+                       DIR *dir;
+
+                       path[len] = 0;
+                       strcpy(path + len, case_check_filename);
+                       case_file = fopen(path, "w");
+                       if (!case_file)
+                               die_errno(_("cannot open '%s'"), path);
+                       fclose(case_file);
+
+                       path[len] = 0;
+                       dir = opendir(path);
+                       if (!dir)
+                               die_errno(_("cannot opendir '%s'"), path);
+
+                       while ( (dirent = readdir(dir)) ) {
+                               if (0 == strcmp(case_check_filename, 
dirent->d_name)) {
+                                       completely_insensitive_fs = 0;
+                                       break;
+                               }
+                       }
+
+                       closedir(dir);
+                       path[len] = 0;
+                       strcpy(path + len, case_check_filename);
+                       unlink(path);
+
+                       if (completely_insensitive_fs)
+                               git_config_set("core.ignorecase", "true");
+               }
                probe_utf8_pathname_composition(path, len);
        }
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to