git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/2] init-db.c: honor case on case preserving fs

From
Reuben Hawkins <reubenhwk@gmail.com>
Date
Feb 1, 2014, 09:14 UTC
Message-ID
<1391246067-30499-1-git-send-email-reubenhwk@gmail.com>

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 <reubenhwk@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
Next: Reuben Hawkins
Message 1 of 6 in “init-db.c: honor case on case preserving fs”
  1. 1/2 init-db.c: honor case on case preserving fsReuben Hawkins, Feb 1, 2014
  2. 2/2 init-db.c: factor out probe_case_sensitivity funcReuben Hawkins, Feb 1, 2014
  3. Torsten BögershausenFeb 1, 2014
  4. Junio C HamanoFeb 2, 2014
  5. Dmitry PotapovFeb 1, 2014
  6. Dmitry PotapovFeb 2, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.