{"thread":{"id":"24755","subject":"[PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","startedAt":"2010-08-16T19:38:08Z","lastAt":"2010-08-30T20:13:07Z","messageCount":26,"participants":["Johannes Sixt","Robert Buck","Ævar Arnfjörð Bjarmason","Joshua Jensen","Junio C Hamano","Jonathan Nieder"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"148200","messageId":"cover.1281985411.git.j6t@kdbg.org","threadId":"24755","inReplyTo":null,"subject":"[PATCH 0/6] Extensions of core.ignorecase=true support","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-08-16T19:38:08Z","receivedAt":"2010-08-16T19:38:08Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"The following patch series extends the core.ignorecase=true support to\nhandle case insensitive comparisons for the .gitignore file, git status,\nand git ls-files.  git add and git fast-import will fold the case of the\nfile being added, matching that of an already added directory entry.  Case\nfolding is also applied to git fast-import for renames, copies, and deletes.\n\nThe most notable benefit, IMO, is that the case of directories in the\nworktree does not matter if, and only if, the directory exists already in\nthe index with some different case variant.  This helps applications on\nWindows that change the case even of directories in unpredictable ways.\nJoshua mentioned Perforce as the primary example.\n\nConcerning the implementation, Joshua explained when he initially submitted\nthe series to the msysgit mailing list:\n\n git status and add both use an update made to name-hash.c where \n directories, specifically names with a trailing slash, can be looked up \n in a case insensitive manner. After trying a myriad of solutions, this \n seemed to be the cleanest. Does anyone see a problem with embedding the \n directory names in the same hash as the file names? I couldn't find one, \n especially since I append a slash to each directory name.\n\n The git add path case folding functionality is a somewhat radical \n departure from what Git does now. It is described in detail in patch 5. \n Does anyone have any concerns?\n\nI support the idea of this patch, and I can confirm that it works: I've\nused this series in production both with core.ignorecase set to true and\nto false, and in the former case, with directories and files with case\ndifferent from the index.\n\nJoshua Jensen (6):\n  Add string comparison functions that respect the ignore_case\n    variable.\n  Case insensitivity support for .gitignore via core.ignorecase\n  Add case insensitivity support for directories when using git status\n  Add case insensitivity support when using git ls-files\n  Support case folding for git add when core.ignorecase=true\n  Support case folding in git fast-import when core.ignorecase=true\n\n dir.c         |  105 ++++++++++++++++++++++++++++++++++++++++++++++----------\n dir.h         |    4 ++\n fast-import.c |    7 ++--\n name-hash.c   |   72 ++++++++++++++++++++++++++++++++++++++-\n read-cache.c  |   23 ++++++++++++\n 5 files changed, 188 insertions(+), 23 deletions(-)\n"},{"id":"148197","messageId":"513deaf9e8915473f7fc7f32401b17e383cb7d3a.1281985411.git.j6t@kdbg.org","threadId":"24755","inReplyTo":"cover.1281985411.git.j6t@kdbg.org","subject":"[PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-08-16T19:38:09Z","receivedAt":"2010-08-16T19:38:09Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"From: Joshua Jensen <jjensen@workspacewhiz.com>\n\nMultiple locations within this patch series alter a case sensitive\nstring comparison call such as strcmp() to be a call to a string\ncomparison call that selects case comparison based on the global\nignore_case variable. Behaviorally, when core.ignorecase=false, the\n*_icase() versions are functionally equivalent to their C runtime\ncounterparts.  When core.ignorecase=true, the *_icase() versions perform\na case insensitive comparison.\n\nLike Linus' earlier ignorecase patch, these may ignore filename\nconventions on certain file systems. By isolating filename comparisons\nto certain functions, support for those filename conventions may be more\neasily met.\n\nSigned-off-by: Joshua Jensen <jjensen@workspacewhiz.com>\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n dir.c |   16 ++++++++++++++++\n dir.h |    4 ++++\n 2 files changed, 20 insertions(+), 0 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 133f472..4d001fd 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -18,6 +18,22 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, in\n \tint check_only, const struct path_simplify *simplify);\n static int get_dtype(struct dirent *de, const char *path, int len);\n \n+/* helper string functions with support for the ignore_case flag */\n+int strcmp_icase(const char *a, const char *b)\n+{\n+\treturn ignore_case ? strcasecmp(a, b) : strcmp(a, b);\n+}\n+\n+int strncmp_icase(const char *a, const char *b, size_t count)\n+{\n+\treturn ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);\n+}\n+\n+int fnmatch_icase(const char *pattern, const char *string, int flags)\n+{\n+\treturn fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));\n+}\n+\n static int common_prefix(const char **pathspec)\n {\n \tconst char *path, *slash, *next;\ndiff --git a/dir.h b/dir.h\nindex 278d84c..b3e2104 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -101,4 +101,8 @@ extern int remove_dir_recursively(struct strbuf *path, int flag);\n /* tries to remove the path with empty directories along it, ignores ENOENT */\n extern int remove_path(const char *path);\n \n+extern int strcmp_icase(const char *a, const char *b);\n+extern int strncmp_icase(const char *a, const char *b, size_t count);\n+extern int fnmatch_icase(const char *pattern, const char *string, int flags);\n+\n #endif\n-- \n1.7.1.402.gf1eeb\n"},{"id":"148198","messageId":"0207df477b402bacf5792a6c9cb410e924501b27.1281985411.git.j6t@kdbg.org","threadId":"24755","inReplyTo":"cover.1281985411.git.j6t@kdbg.org","subject":"[PATCH 2/6] Case insensitivity support for .gitignore via core.ignorecase","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-08-16T19:38:10Z","receivedAt":"2010-08-16T19:38:10Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"From: Joshua Jensen <jjensen@workspacewhiz.com>\n\nThis is especially beneficial when using Windows and Perforce and the\ngit-p4 bridge. Internally, Perforce preserves a given file's full path\nincluding its case at the time it was added to the Perforce repository.\nWhen syncing a file down via Perforce, missing directories are created,\nif necessary, using the case as stored with the filename. Unfortunately,\ntwo files in the same directory can have differing cases for their\nrespective paths, such as /diRa/file1.c and /DirA/file2.c. Depending on\nsync order, DirA/ may get created instead of diRa/.\n\nIt is possible to handle directory names in a case insensitive manner\nwithout this patch, but it is highly inconvenient, requiring each\ncharacter to be specified like so: [Bb][Uu][Ii][Ll][Dd]. With this patch, the\ngitignore exclusions honor the core.ignorecase=true configuration\nsetting and make the process less error prone. The above is specified\nlike so: Build\n\nSigned-off-by: Joshua Jensen <jjensen@workspacewhiz.com>\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n dir.c |   12 ++++++------\n 1 files changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 4d001fd..be21c20 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -390,14 +390,14 @@ int excluded_from_list(const char *pathname,\n \t\t\tif (x->flags & EXC_FLAG_NODIR) {\n \t\t\t\t/* match basename */\n \t\t\t\tif (x->flags & EXC_FLAG_NOWILDCARD) {\n-\t\t\t\t\tif (!strcmp(exclude, basename))\n+\t\t\t\t\tif (!strcmp_icase(exclude, basename))\n \t\t\t\t\t\treturn to_exclude;\n \t\t\t\t} else if (x->flags & EXC_FLAG_ENDSWITH) {\n \t\t\t\t\tif (x->patternlen - 1 <= pathlen &&\n-\t\t\t\t\t    !strcmp(exclude + 1, pathname + pathlen - x->patternlen + 1))\n+\t\t\t\t\t    !strcmp_icase(exclude + 1, pathname + pathlen - x->patternlen + 1))\n \t\t\t\t\t\treturn to_exclude;\n \t\t\t\t} else {\n-\t\t\t\t\tif (fnmatch(exclude, basename, 0) == 0)\n+\t\t\t\t\tif (fnmatch_icase(exclude, basename, 0) == 0)\n \t\t\t\t\t\treturn to_exclude;\n \t\t\t\t}\n \t\t\t}\n@@ -412,14 +412,14 @@ int excluded_from_list(const char *pathname,\n \n \t\t\t\tif (pathlen < baselen ||\n \t\t\t\t    (baselen && pathname[baselen-1] != '/') ||\n-\t\t\t\t    strncmp(pathname, x->base, baselen))\n+\t\t\t\t    strncmp_icase(pathname, x->base, baselen))\n \t\t\t\t    continue;\n \n \t\t\t\tif (x->flags & EXC_FLAG_NOWILDCARD) {\n-\t\t\t\t\tif (!strcmp(exclude, pathname + baselen))\n+\t\t\t\t\tif (!strcmp_icase(exclude, pathname + baselen))\n \t\t\t\t\t\treturn to_exclude;\n \t\t\t\t} else {\n-\t\t\t\t\tif (fnmatch(exclude, pathname+baselen,\n+\t\t\t\t\tif (fnmatch_icase(exclude, pathname+baselen,\n \t\t\t\t\t\t    FNM_PATHNAME) == 0)\n \t\t\t\t\t    return to_exclude;\n \t\t\t\t}\n-- \n1.7.1.402.gf1eeb\n"},{"id":"148203","messageId":"ff426cde57168ff68a4ec9042c2b6fa5b76a55be.1281985411.git.j6t@kdbg.org","threadId":"24755","inReplyTo":"cover.1281985411.git.j6t@kdbg.org","subject":"[PATCH 3/6] Add case insensitivity support for directories when using git status","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-08-16T19:38:11Z","receivedAt":"2010-08-16T19:38:11Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"From: Joshua Jensen <jjensen@workspacewhiz.com>\n\nWhen using a case preserving but case insensitive file system, directory\ncase can differ but still refer to the same physical directory.  git\nstatus reports the directory with the alternate case as an Untracked\nfile.  (That is, when mydir/filea.txt is added to the repository and\nthen the directory on disk is renamed from mydir/ to MyDir/, git status\nshows MyDir/ as being untracked.)\n\nSupport has been added in name-hash.c for hashing directories with a\nterminating slash into the name hash. When index_name_exists() is called\nwith a directory (a name with a terminating slash), the name is not\nfound via the normal cache_name_compare() call, but it is found in the\nslow_same_name() function.\n\nAdditionally, in dir.c, directory_exists_in_index_icase() allows newly\nadded directories deeper in the directory chain to be identified.\n\nUltimately, it would be better if the file list was read in case\ninsensitive alphabetical order from disk, but this change seems to\nsuffice for now.\n\nThe end result is the directory is looked up in a case insensitive\nmanner and does not show in the Untracked files list.\n\nSigned-off-by: Joshua Jensen <jjensen@workspacewhiz.com>\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n dir.c       |   39 +++++++++++++++++++++++++++++++-\n name-hash.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 109 insertions(+), 2 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex be21c20..f80e091 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -485,6 +485,38 @@ enum exist_status {\n };\n \n /*\n+ * Do not use the alphabetically stored index to look up\n+ * the directory name; instead, use the case insensitive\n+ * name hash.\n+ */\n+static enum exist_status directory_exists_in_index_icase(const char *dirname, int len)\n+{\n+\tstruct cache_entry *ce = index_name_exists(&the_index, dirname, len + 1, ignore_case);\n+\tif (!ce)\n+\t\treturn index_nonexistent;\n+\n+\tunsigned char endchar = ce->name[len];\n+\n+\t/*\n+\t * The cache_entry structure returned will contain this dirname\n+\t * and possibly additional path components.\n+\t */\n+\tif (endchar == '/')\n+\t\treturn index_directory;\n+\n+\t/*\n+\t * If there are no additional path components, then this cache_entry\n+\t * represents a submodule.  Submodules, despite being directories,\n+\t * are stored in the cache without a closing slash.\n+\t */\n+\tif (!endchar && S_ISGITLINK(ce->ce_mode))\n+\t\treturn index_gitdir;\n+\n+\t/* This should never be hit, but it exists just in case. */\n+\treturn index_nonexistent;\n+}\n+\n+/*\n  * The index sorts alphabetically by entry name, which\n  * means that a gitlink sorts as '\\0' at the end, while\n  * a directory (which is defined not as an entry, but as\n@@ -493,7 +525,12 @@ enum exist_status {\n  */\n static enum exist_status directory_exists_in_index(const char *dirname, int len)\n {\n-\tint pos = cache_name_pos(dirname, len);\n+\tint pos;\n+\n+\tif (ignore_case)\n+\t\treturn directory_exists_in_index_icase(dirname, len);\n+\n+\tpos = cache_name_pos(dirname, len);\n \tif (pos < 0)\n \t\tpos = -pos-1;\n \twhile (pos < active_nr) {\ndiff --git a/name-hash.c b/name-hash.c\nindex 0031d78..c6b6a3f 100644\n--- a/name-hash.c\n+++ b/name-hash.c\n@@ -32,6 +32,42 @@ static unsigned int hash_name(const char *name, int namelen)\n \treturn hash;\n }\n \n+static void hash_index_entry_directories(struct index_state *istate, struct cache_entry *ce)\n+{\n+\t/*\n+\t * Throw each directory component in the hash for quick lookup\n+\t * during a git status. Directory components are stored with their\n+\t * closing slash.  Despite submodules being a directory, they never\n+\t * reach this point, because they are stored without a closing slash\n+\t * in the cache.\n+\t *\n+\t * Note that the cache_entry stored with the directory does not\n+\t * represent the directory itself.  It is a pointer to an existing\n+\t * filename, and its only purpose is to represent existence of the\n+\t * directory in the cache.  It is very possible multiple directory\n+\t * hash entries may point to the same cache_entry.\n+\t */\n+\tunsigned int hash;\n+\tvoid **pos;\n+\n+\tconst char *ptr = ce->name;\n+\twhile (*ptr) {\n+\t\twhile (*ptr && *ptr != '/')\n+\t\t\t++ptr;\n+\t\tif (*ptr == '/') {\n+\t\t\t++ptr;\n+\t\t\thash = hash_name(ce->name, ptr - ce->name);\n+\t\t\tif (!lookup_hash(hash, &istate->name_hash)) {\n+\t\t\t\tpos = insert_hash(hash, ce, &istate->name_hash);\n+\t\t\t\tif (pos) {\n+\t\t\t\t\tce->next = *pos;\n+\t\t\t\t\t*pos = ce;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t}\n+}\n+\n static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)\n {\n \tvoid **pos;\n@@ -47,6 +83,9 @@ static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)\n \t\tce->next = *pos;\n \t\t*pos = ce;\n \t}\n+\n+\tif (ignore_case)\n+\t\thash_index_entry_directories(istate, ce);\n }\n \n static void lazy_init_name_hash(struct index_state *istate)\n@@ -97,7 +136,21 @@ static int same_name(const struct cache_entry *ce, const char *name, int namelen\n \tif (len == namelen && !cache_name_compare(name, namelen, ce->name, len))\n \t\treturn 1;\n \n-\treturn icase && slow_same_name(name, namelen, ce->name, len);\n+\tif (!icase)\n+\t\treturn 0;\n+\n+\t/*\n+\t * If the entry we're comparing is a filename (no trailing slash), then compare\n+\t * the lengths exactly.\n+\t */\n+\tif (name[namelen - 1] != '/')\n+\t\treturn slow_same_name(name, namelen, ce->name, len);\n+\n+\t/*\n+\t * For a directory, we point to an arbitrary cache_entry filename.  Just\n+\t * make sure the directory portion matches.\n+\t */\n+\treturn slow_same_name(name, namelen, ce->name, namelen < len ? namelen : len);\n }\n \n struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int icase)\n@@ -115,5 +168,22 @@ struct cache_entry *index_name_exists(struct index_state *istate, const char *na\n \t\t}\n \t\tce = ce->next;\n \t}\n+\n+\t/*\n+\t * Might be a submodule.  Despite submodules being directories,\n+\t * they are stored in the name hash without a closing slash.\n+\t * When ignore_case is 1, directories are stored in the name hash\n+\t * with their closing slash.\n+\t *\n+\t * The side effect of this storage technique is we have need to\n+\t * remove the slash from name and perform the lookup again without\n+\t * the slash.  If a match is made, S_ISGITLINK(ce->mode) will be\n+\t * true.\n+\t */\n+\tif (icase && name[namelen - 1] == '/') {\n+\t\tce = index_name_exists(istate, name, namelen - 1, icase);\n+\t\tif (ce && S_ISGITLINK(ce->ce_mode))\n+\t\t\treturn ce;\n+\t}\n \treturn NULL;\n }\n-- \n1.7.1.402.gf1eeb\n"},{"id":"148202","messageId":"f7e0d9cf470a519f7a7a35ab64a635f5675e9c7d.1281985411.git.j6t@kdbg.org","threadId":"24755","inReplyTo":"cover.1281985411.git.j6t@kdbg.org","subject":"[PATCH 4/6] Add case insensitivity support when using git ls-files","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-08-16T19:38:12Z","receivedAt":"2010-08-16T19:38:12Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"From: Joshua Jensen <jjensen@workspacewhiz.com>\n\nWhen mydir/filea.txt is added, mydir/ is renamed to MyDir/, and\nMyDir/fileb.txt is added, running git ls-files mydir only shows\nmydir/filea.txt. Running git ls-files MyDir shows MyDir/fileb.txt.\nRunning git ls-files mYdIR shows nothing.\n\nWith this patch running git ls-files for mydir, MyDir, and mYdIR shows\nmydir/filea.txt and MyDir/fileb.txt.\n\nWildcards are not handled case insensitively in this patch. Example:\nMyDir/aBc/file.txt is added. git ls-files MyDir/a* works fine, but git\nls-files mydir/a* does not.\n\nSigned-off-by: Joshua Jensen <jjensen@workspacewhiz.com>\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n dir.c |   38 ++++++++++++++++++++++++++------------\n 1 files changed, 26 insertions(+), 12 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex f80e091..af5f54f 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -107,16 +107,30 @@ static int match_one(const char *match, const char *name, int namelen)\n \tif (!*match)\n \t\treturn MATCHED_RECURSIVELY;\n \n-\tfor (;;) {\n-\t\tunsigned char c1 = *match;\n-\t\tunsigned char c2 = *name;\n-\t\tif (c1 == '\\0' || is_glob_special(c1))\n-\t\t\tbreak;\n-\t\tif (c1 != c2)\n-\t\t\treturn 0;\n-\t\tmatch++;\n-\t\tname++;\n-\t\tnamelen--;\n+\tif (ignore_case) {\n+\t\tfor (;;) {\n+\t\t\tunsigned char c1 = tolower(*match);\n+\t\t\tunsigned char c2 = tolower(*name);\n+\t\t\tif (c1 == '\\0' || is_glob_special(c1))\n+\t\t\t\tbreak;\n+\t\t\tif (c1 != c2)\n+\t\t\t\treturn 0;\n+\t\t\tmatch++;\n+\t\t\tname++;\n+\t\t\tnamelen--;\n+\t\t}\n+\t} else {\n+\t\tfor (;;) {\n+\t\t\tunsigned char c1 = *match;\n+\t\t\tunsigned char c2 = *name;\n+\t\t\tif (c1 == '\\0' || is_glob_special(c1))\n+\t\t\t\tbreak;\n+\t\t\tif (c1 != c2)\n+\t\t\t\treturn 0;\n+\t\t\tmatch++;\n+\t\t\tname++;\n+\t\t\tnamelen--;\n+\t\t}\n \t}\n \n \n@@ -125,8 +139,8 @@ static int match_one(const char *match, const char *name, int namelen)\n \t * we need to match by fnmatch\n \t */\n \tmatchlen = strlen(match);\n-\tif (strncmp(match, name, matchlen))\n-\t\treturn !fnmatch(match, name, 0) ? MATCHED_FNMATCH : 0;\n+\tif (strncmp_icase(match, name, matchlen))\n+\t\treturn !fnmatch_icase(match, name, 0) ? MATCHED_FNMATCH : 0;\n \n \tif (namelen == matchlen)\n \t\treturn MATCHED_EXACTLY;\n-- \n1.7.1.402.gf1eeb\n"},{"id":"148201","messageId":"0071a1bcd83200e693d73049672fa2d6ac73dbbc.1281985411.git.j6t@kdbg.org","threadId":"24755","inReplyTo":"cover.1281985411.git.j6t@kdbg.org","subject":"[PATCH 5/6] Support case folding for git add when core.ignorecase=true","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-08-16T19:38:13Z","receivedAt":"2010-08-16T19:38:13Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"From: Joshua Jensen <jjensen@workspacewhiz.com>\n\nWhen MyDir/ABC/filea.txt is added to Git, the disk directory MyDir/ABC/\nis renamed to mydir/aBc/, and then mydir/aBc/fileb.txt is added, the\nindex will contain MyDir/ABC/filea.txt and mydir/aBc/fileb.txt. Although\nthe earlier portions of this patch series account for those differences\nin case, this patch makes the pathing consistent by folding the case of\nnewly added files against the first file added with that path.\n\nIn read-cache.c's add_to_index(), the index_name_exists() support used\nfor git status's case insensitive directory lookups is used to find the\nproper directory case according to what the user already checked in.\nThat is, MyDir/ABC/'s case is used to alter the stored path for\nfileb.txt to MyDir/ABC/fileb.txt (instead of mydir/aBc/fileb.txt).\n\nThis is especially important when cloning a repository to a case\nsensitive file system. MyDir/ABC/ and mydir/aBc/ exist in the same\ndirectory on a Windows machine, but on Linux, the files exist in two\nseparate directories. The update to add_to_index(), in effect, treats a\nWindows file system as case sensitive by making path case consistent.\n\nSigned-off-by: Joshua Jensen <jjensen@workspacewhiz.com>\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n read-cache.c |   23 +++++++++++++++++++++++\n 1 files changed, 23 insertions(+), 0 deletions(-)\n\ndiff --git a/read-cache.c b/read-cache.c\nindex f1f789b..ae1366a 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -608,6 +608,29 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,\n \t\tce->ce_mode = ce_mode_from_stat(ent, st_mode);\n \t}\n \n+\t/* When core.ignorecase=true, determine if a directory of the same name but differing\n+\t * case already exists within the Git repository.  If it does, ensure the directory\n+\t * case of the file being added to the repository matches (is folded into) the existing\n+\t * entry's directory case.\n+\t */\n+\tif (ignore_case) {\n+\t\tconst char *startPtr = ce->name;\n+\t\tconst char *ptr = startPtr;\n+\t\twhile (*ptr) {\n+\t\t\twhile (*ptr && *ptr != '/')\n+\t\t\t\t++ptr;\n+\t\t\tif (*ptr == '/') {\n+\t\t\t\tstruct cache_entry *foundce;\n+\t\t\t\t++ptr;\n+\t\t\t\tfoundce = index_name_exists(&the_index, ce->name, ptr - ce->name, ignore_case);\n+\t\t\t\tif (foundce) {\n+\t\t\t\t\tmemcpy((void*)startPtr, foundce->name + (startPtr - ce->name), ptr - startPtr);\n+\t\t\t\t\tstartPtr = ptr;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t}\n+\n \talias = index_name_exists(istate, ce->name, ce_namelen(ce), ignore_case);\n \tif (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, st, ce_option)) {\n \t\t/* Nothing changed, really */\n-- \n1.7.1.402.gf1eeb\n"},{"id":"148199","messageId":"8cc8aeccf7fb9af6a67487a55cfacb19c9910ecd.1281985411.git.j6t@kdbg.org","threadId":"24755","inReplyTo":"cover.1281985411.git.j6t@kdbg.org","subject":"[PATCH 6/6] Support case folding in git fast-import when core.ignorecase=true","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-08-16T19:38:14Z","receivedAt":"2010-08-16T19:38:14Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"From: Joshua Jensen <jjensen@workspacewhiz.com>\n\nWhen core.ignorecase=true, imported file paths will be folded to match\nexisting directory case.\n\nSigned-off-by: Joshua Jensen <jjensen@workspacewhiz.com>\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n fast-import.c |    7 ++++---\n 1 files changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/fast-import.c b/fast-import.c\nindex 1e5d66e..82df00e 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -156,6 +156,7 @@ Format of STDIN stream:\n #include \"csum-file.h\"\n #include \"quote.h\"\n #include \"exec_cmd.h\"\n+#include \"dir.h\"\n \n #define PACK_ID_BITS 16\n #define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)\n@@ -1461,7 +1462,7 @@ static int tree_content_set(\n \n \tfor (i = 0; i < t->entry_count; i++) {\n \t\te = t->entries[i];\n-\t\tif (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {\n+\t\tif (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {\n \t\t\tif (!slash1) {\n \t\t\t\tif (!S_ISDIR(mode)\n \t\t\t\t\t\t&& e->versions[1].mode == mode\n@@ -1527,7 +1528,7 @@ static int tree_content_remove(\n \n \tfor (i = 0; i < t->entry_count; i++) {\n \t\te = t->entries[i];\n-\t\tif (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {\n+\t\tif (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {\n \t\t\tif (!slash1 || !S_ISDIR(e->versions[1].mode))\n \t\t\t\tgoto del_entry;\n \t\t\tif (!e->tree)\n@@ -1577,7 +1578,7 @@ static int tree_content_get(\n \n \tfor (i = 0; i < t->entry_count; i++) {\n \t\te = t->entries[i];\n-\t\tif (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {\n+\t\tif (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {\n \t\t\tif (!slash1) {\n \t\t\t\tmemcpy(leaf, e, sizeof(*leaf));\n \t\t\t\tif (e->tree && is_null_sha1(e->versions[1].sha1))\n-- \n1.7.1.402.gf1eeb\n"},{"id":"148304","messageId":"AANLkTi=0j_JFWBp=kJG6v+YBUxKAiVAVc4UtG0LWmipq@mail.gmail.com","threadId":"24755","inReplyTo":"cover.1281985411.git.j6t@kdbg.org","subject":"Re: [PATCH 0/6] Extensions of core.ignorecase=true support","fromName":"Robert Buck","fromEmail":"buck.robert.j@gmail.com","sentAt":"2010-08-17T19:36:13Z","receivedAt":"2010-08-17T19:36:13Z","isPatch":true,"sender":{"key":"buck.robert.j@gmail.com","avatar":"https://gravatar.com/avatar/1686742e8ac2595378aac67f26fd638ddaf494194f9af0cb6082c4a7eca1a366?d=mp&s=160"},"body":"While I tend to agree with case-insensitive searches, I would tend to\nquestion the use of a non-case-preserving / last-use methodology\nreminiscent of the days of DOS. I was never terribly fond of DOS nor\nof Windows for Workgroups, and this change smacks of that. That said,\nas an algorithm it is one legitimate option, I just would not tend to\nuse it.\n\nHave you thought of other approaches that are case-preserving /\ncase-insensitive (modern Windows implementations and Mac OS X) or of\ncase-sensitive (UNIX)? What about giving the user the choice?\n\nLooking back at how flexible and simple folks here on this list made\nthe EOL support (the best I have seen to date) what if you followed a\nsimilar approach and provided the flexibility to the users by giving\nthe options to control the behavior themselves, then fall back to\nreasonable defaults if left unspecified?\n\nI would imagine having two properties would be somewhat more useful:\n\ncore.casepreserving=true|false\ncore.caseinsensitive=true|false\n\nFor Unix-centric environments the defaults would be true & false,\nrespectively. For mixed Windows/Unix environments users would\nconfigure it as true & true. A combination of false & true,\nrespectively, would be appropriate for DOS users, but this may be\nanother option for mixed environments. A combination of false & false\nwould be impossible by definition.\n\nWhat this would mean is that searches in the purely Unix world would\nstore and match sensitively; but in such an environment there may be\nissues should any Windows users attempt to work with the repository if\ntwo files having a similar names existed. For Windows users the last\nread operation would overwrite the first (not a good thing).\n\nFor mixed configurations there are two options, the Windows/Mac\noption, and the DOS option.\n\nThe nice thing about case-insensitivity is that when requesting a file\nby name any capitalization can be used. The bad thing, well come to\nthink of it, there is none that I can think of, but for those more\nreligious than I about Unix they may cite otherwise.\n\n-Bob\n\nOn Mon, Aug 16, 2010 at 3:38 PM, Johannes Sixt <j6t@kdbg.org> wrote:\n> The following patch series extends the core.ignorecase=true support to\n> handle case insensitive comparisons for the .gitignore file, git status,\n> and git ls-files.  git add and git fast-import will fold the case of the\n> file being added, matching that of an already added directory entry.  Case\n> folding is also applied to git fast-import for renames, copies, and deletes.\n>\n> The most notable benefit, IMO, is that the case of directories in the\n> worktree does not matter if, and only if, the directory exists already in\n> the index with some different case variant.  This helps applications on\n> Windows that change the case even of directories in unpredictable ways.\n> Joshua mentioned Perforce as the primary example.\n>\n> Concerning the implementation, Joshua explained when he initially submitted\n> the series to the msysgit mailing list:\n>\n>  git status and add both use an update made to name-hash.c where\n>  directories, specifically names with a trailing slash, can be looked up\n>  in a case insensitive manner. After trying a myriad of solutions, this\n>  seemed to be the cleanest. Does anyone see a problem with embedding the\n>  directory names in the same hash as the file names? I couldn't find one,\n>  especially since I append a slash to each directory name.\n>\n>  The git add path case folding functionality is a somewhat radical\n>  departure from what Git does now. It is described in detail in patch 5.\n>  Does anyone have any concerns?\n>\n> I support the idea of this patch, and I can confirm that it works: I've\n> used this series in production both with core.ignorecase set to true and\n> to false, and in the former case, with directories and files with case\n> different from the index.\n>\n> Joshua Jensen (6):\n>  Add string comparison functions that respect the ignore_case\n>    variable.\n>  Case insensitivity support for .gitignore via core.ignorecase\n>  Add case insensitivity support for directories when using git status\n>  Add case insensitivity support when using git ls-files\n>  Support case folding for git add when core.ignorecase=true\n>  Support case folding in git fast-import when core.ignorecase=true\n>\n>  dir.c         |  105 ++++++++++++++++++++++++++++++++++++++++++++++----------\n>  dir.h         |    4 ++\n>  fast-import.c |    7 ++--\n>  name-hash.c   |   72 ++++++++++++++++++++++++++++++++++++++-\n>  read-cache.c  |   23 ++++++++++++\n>  5 files changed, 188 insertions(+), 23 deletions(-)\n>\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n"},{"id":"148308","messageId":"201008172320.17939.j6t@kdbg.org","threadId":"24755","inReplyTo":"AANLkTi=0j_JFWBp=kJG6v+YBUxKAiVAVc4UtG0LWmipq@mail.gmail.com","subject":"Re: [PATCH 0/6] Extensions of core.ignorecase=true support","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-08-17T21:20:17Z","receivedAt":"2010-08-17T21:20:17Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Dienstag, 17. August 2010, Robert Buck wrote:\n> While I tend to agree with case-insensitive searches, I would tend to\n> question the use of a non-case-preserving / last-use methodology\n> reminiscent of the days of DOS.\n\nThere is no \"last-use\" involved. Everything's rather \"first-use\", i.e., \ncase-preserving.\n\n> The nice thing about case-insensitivity is that when requesting a file\n> by name any capitalization can be used. The bad thing, well come to\n> think of it, there is none that I can think of, but for those more\n> religious than I about Unix they may cite otherwise.\n\nWhat do you mean by \"requesting a file\"?\n\ncore.ignorecase is purely about the worktree and the transition of files from \nthe worktree to the index. It is *not* involved when files are moved from the \nindex or the repository to the worktree. In particular, it is not used when \nyou give a pathspec to limit 'git log' results. (Joshua proposed a change \nwhere core.ignorecase would also kick in in this case as well, but this \nchange is not included in this series, and I would not agree to it.)\n\n-- Hannes\n"},{"id":"148333","messageId":"AANLkTi=Fkj-_-wHZN4GY2b+2n0mk7MKV=au0Hm4B+i9d@mail.gmail.com","threadId":"24755","inReplyTo":"201008172320.17939.j6t@kdbg.org","subject":"Re: [PATCH 0/6] Extensions of core.ignorecase=true support","fromName":"Robert Buck","fromEmail":"buck.robert.j@gmail.com","sentAt":"2010-08-18T02:41:25Z","receivedAt":"2010-08-18T02:41:25Z","isPatch":true,"sender":{"key":"buck.robert.j@gmail.com","avatar":"https://gravatar.com/avatar/1686742e8ac2595378aac67f26fd638ddaf494194f9af0cb6082c4a7eca1a366?d=mp&s=160"},"body":"So apparently when core.ignorecase=true, this really means\ncasepreserving=false, casesensitive=true. Yet when\ncore.ignorecase=false it actually means casepreserving=true,\ncasesensitive=true. That's what I infer from the git-config\ndocumentation. Would you agree?\n\nOn Tue, Aug 17, 2010 at 5:20 PM, Johannes Sixt <j6t@kdbg.org> wrote:\n> On Dienstag, 17. August 2010, Robert Buck wrote:\n>> While I tend to agree with case-insensitive searches, I would tend to\n>> question the use of a non-case-preserving / last-use methodology\n>> reminiscent of the days of DOS.\n>\n> There is no \"last-use\" involved. Everything's rather \"first-use\", i.e.,\n> case-preserving.\n>\n>> The nice thing about case-insensitivity is that when requesting a file\n>> by name any capitalization can be used. The bad thing, well come to\n>> think of it, there is none that I can think of, but for those more\n>> religious than I about Unix they may cite otherwise.\n>\n> What do you mean by \"requesting a file\"?\n>\n> core.ignorecase is purely about the worktree and the transition of files from\n> the worktree to the index. It is *not* involved when files are moved from the\n> index or the repository to the worktree. In particular, it is not used when\n> you give a pathspec to limit 'git log' results. (Joshua proposed a change\n> where core.ignorecase would also kick in in this case as well, but this\n> change is not included in this series, and I would not agree to it.)\n\nSo what I am hearing is that unless one sets core.ignorecase, in mixed\nenvironments you are in for a world of hurt; you'd end up with Foo and\nfoo from the Unix side of the house, and on Macs or Windows the last\nfile materialized from the index or repository into the working\ndirectory would clobber the first one materialized, potentially\nintroducing relatively quiescent bugs that could make their way into\nproduction environments.\n"},{"id":"148361","messageId":"AANLkTi=mH9WPbJMKXRrgvdcuqZfHj1kC49M0jKUhaYeS@mail.gmail.com","threadId":"24755","inReplyTo":"513deaf9e8915473f7fc7f32401b17e383cb7d3a.1281985411.git.j6t@kdbg.org","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-18T12:52:39Z","receivedAt":"2010-08-18T12:52:39Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Mon, Aug 16, 2010 at 19:38, Johannes Sixt <j6t@kdbg.org> wrote:\n\n> +       return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));\n\nOn Solaris 10:\n\ndir.c: In function `fnmatch_icase':\ndir.c:34: error: `FNM_CASEFOLD' undeclared (first use in this function)\ndir.c:34: error: (Each undeclared identifier is reported only once\ndir.c:34: error: for each function it appears in.)\n"},{"id":"148363","messageId":"AANLkTi=V1-vNjA36BXC5OD+ek-S_1RLVBFt==atxtJk5@mail.gmail.com","threadId":"24755","inReplyTo":"AANLkTi=mH9WPbJMKXRrgvdcuqZfHj1kC49M0jKUhaYeS@mail.gmail.com","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-18T12:53:52Z","receivedAt":"2010-08-18T12:53:52Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Wed, Aug 18, 2010 at 12:52, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n> On Mon, Aug 16, 2010 at 19:38, Johannes Sixt <j6t@kdbg.org> wrote:\n>\n>> +       return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));\n>\n> On Solaris 10:\n>\n> dir.c: In function `fnmatch_icase':\n> dir.c:34: error: `FNM_CASEFOLD' undeclared (first use in this function)\n> dir.c:34: error: (Each undeclared identifier is reported only once\n> dir.c:34: error: for each function it appears in.)\n\nActually, reading the fnmatch manpage it's not just Solaris, but all\nnon-GNU systems:\n\n       FNM_CASEFOLD\n              If this flag (a GNU extension) is set, the pattern is\nmatched case-insensitively.\n"},{"id":"148392","messageId":"4C6C01A9.4080306@workspacewhiz.com","threadId":"24755","inReplyTo":"AANLkTi=V1-vNjA36BXC5OD+ek-S_1RLVBFt==atxtJk5@mail.gmail.com","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Joshua Jensen","fromEmail":"jjensen@workspacewhiz.com","sentAt":"2010-08-18T15:52:09Z","receivedAt":"2010-08-18T15:52:09Z","isPatch":true,"sender":{"key":"jjensen@workspacewhiz.com","avatar":"https://avatars.githubusercontent.com/u/111687?v=4"},"body":"  ----- Original Message -----\nFrom: Ævar Arnfjörð Bjarmason\nDate: 8/18/2010 6:53 AM\n> On Wed, Aug 18, 2010 at 12:52, Ævar Arnfjörð Bjarmason<avarab@gmail.com>  wrote:\n>> On Mon, Aug 16, 2010 at 19:38, Johannes Sixt<j6t@kdbg.org>  wrote:\n>>> +       return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));\n>> On Solaris 10:\n>>\n>> dir.c: In function `fnmatch_icase':\n>> dir.c:34: error: `FNM_CASEFOLD' undeclared (first use in this function)\n>> dir.c:34: error: (Each undeclared identifier is reported only once\n>> dir.c:34: error: for each function it appears in.)\n> Actually, reading the fnmatch manpage it's not just Solaris, but all\n> non-GNU systems:\n>\n>         FNM_CASEFOLD - If this flag (a GNU extension) is set, the pattern is matched case-insensitively\nWell, that's no good.  :(\n\nThanks for the research.  It helps tremendously.\n\nOne easy way out of this situation would be to duplicate the GNU \nfnmatch() into fnmatch_icase().  I have not looked at the source code, \nso it may not be possible.  If it can be copied in, does anyone object?\n\nI'll also look for a non-GNU function that may work.\n\nJosh\n"},{"id":"148393","messageId":"AANLkTinwQqwjmeNfiUE6LiZtbBhEEFyisZXUgF9_b+2Q@mail.gmail.com","threadId":"24755","inReplyTo":"4C6C01A9.4080306@workspacewhiz.com","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-18T16:07:12Z","receivedAt":"2010-08-18T16:07:12Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Wed, Aug 18, 2010 at 15:52, Joshua Jensen <jjensen@workspacewhiz.com> wrote:\n>  ----- Original Message -----\n> From: Ævar Arnfjörð Bjarmason\n> Date: 8/18/2010 6:53 AM\n>>\n>> On Wed, Aug 18, 2010 at 12:52, Ævar Arnfjörð Bjarmason<avarab@gmail.com>\n>>  wrote:\n>>>\n>>> On Mon, Aug 16, 2010 at 19:38, Johannes Sixt<j6t@kdbg.org>  wrote:\n>>>>\n>>>> +       return fnmatch(pattern, string, flags | (ignore_case ?\n>>>> FNM_CASEFOLD : 0));\n>>>\n>>> On Solaris 10:\n>>>\n>>> dir.c: In function `fnmatch_icase':\n>>> dir.c:34: error: `FNM_CASEFOLD' undeclared (first use in this function)\n>>> dir.c:34: error: (Each undeclared identifier is reported only once\n>>> dir.c:34: error: for each function it appears in.)\n>>\n>> Actually, reading the fnmatch manpage it's not just Solaris, but all\n>> non-GNU systems:\n>>\n>>        FNM_CASEFOLD - If this flag (a GNU extension) is set, the pattern\n>> is matched case-insensitively\n>\n> Well, that's no good.  :(\n>\n> Thanks for the research.  It helps tremendously.\n>\n> One easy way out of this situation would be to duplicate the GNU fnmatch()\n> into fnmatch_icase().  I have not looked at the source code, so it may not\n> be possible.  If it can be copied in, does anyone object?\n>\n> I'll also look for a non-GNU function that may work.\n\nAccording to some further research at least FreeBSD and NetBSD have\ncopied this GNU extension. You may find their versions easier to\nintegrate.\n"},{"id":"148399","messageId":"201008182031.10197.j6t@kdbg.org","threadId":"24755","inReplyTo":"AANLkTi=Fkj-_-wHZN4GY2b+2n0mk7MKV=au0Hm4B+i9d@mail.gmail.com","subject":"Re: [PATCH 0/6] Extensions of core.ignorecase=true support","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-08-18T18:31:09Z","receivedAt":"2010-08-18T18:31:09Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Mittwoch, 18. August 2010, Robert Buck wrote:\n> So apparently when core.ignorecase=true, this really means\n> casepreserving=false, casesensitive=true.\n\nNo. When an entry enters the index from the worktree, an existing entry is \nreused and the index entry's case is preserved, where existence is determined \nin a case-insensitive manner[*]; if the entry is new, the case is preserved.\n\nIn the oppsite direction, case preservation depends entirely on the \ncapabilities of the file system.\n\n[*] The new part of this series is that this case-insensitive existence test \nhappens on for the entire path, and not just the file name part.\n\n> So what I am hearing is that unless one sets core.ignorecase, in mixed\n> environments you are in for a world of hurt; you'd end up with Foo and\n> foo from the Unix side of the house, and on Macs or Windows the last\n> file materialized from the index or repository into the working\n> directory would clobber the first one materialized,\n\ncore.ignorecase is not designed to help this case. It is a \"Doctor, it hurts \nwhen I poke myself in the eye\" problem. Don't have both foo and Foo in your \nrepository if you go cross-platform. The git repository format is not \ndesigned to treat them as identical, and no configuration option alters this.\n\n-- Hannes\n"},{"id":"148400","messageId":"201008182032.40375.j6t@kdbg.org","threadId":"24755","inReplyTo":"AANLkTinwQqwjmeNfiUE6LiZtbBhEEFyisZXUgF9_b+2Q@mail.gmail.com","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-08-18T18:32:40Z","receivedAt":"2010-08-18T18:32:40Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Mittwoch, 18. August 2010, Ævar Arnfjörð Bjarmason wrote:\n> According to some further research at least FreeBSD and NetBSD have\n> copied this GNU extension. You may find their versions easier to\n> integrate.\n\nWe already have a GNU fnmatch in compat/fnmatch.\n\n-- Hannes\n"},{"id":"148403","messageId":"AANLkTimWtdobYk-a8zz1dLS6xPMhOBX-y4v6jxrH-cQK@mail.gmail.com","threadId":"24755","inReplyTo":"201008182032.40375.j6t@kdbg.org","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-18T18:58:00Z","receivedAt":"2010-08-18T18:58:00Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Wed, Aug 18, 2010 at 18:32, Johannes Sixt <j6t@kdbg.org> wrote:\n> On Mittwoch, 18. August 2010, Ævar Arnfjörð Bjarmason wrote:\n>> According to some further research at least FreeBSD and NetBSD have\n>> copied this GNU extension. You may find their versions easier to\n>> integrate.\n>\n> We already have a GNU fnmatch in compat/fnmatch.\n\nI didn't spot that. But until now it's only been used for Windows,\nthere isn't a NO_* flag you can set to compile it in.\n"},{"id":"148700","messageId":"7vpqxb5cwl.fsf@alter.siamese.dyndns.org","threadId":"24755","inReplyTo":"cover.1281985411.git.j6t@kdbg.org","subject":"Re: [PATCH 0/6] Extensions of core.ignorecase=true support","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-08-22T07:23:22Z","receivedAt":"2010-08-22T07:23:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j6t@kdbg.org> writes:\n\n> I support the idea of this patch, and I can confirm that it works: I've\n> used this series in production both with core.ignorecase set to true and\n> to false, and in the former case, with directories and files with case\n> different from the index.\n\nThanks\n"},{"id":"149226","messageId":"AANLkTimtmudtWccRS==LrO_JrPmAJ7HzA6CU0ALbDZcV@mail.gmail.com","threadId":"24755","inReplyTo":"201008182032.40375.j6t@kdbg.org","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-29T19:39:34Z","receivedAt":"2010-08-29T19:39:34Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Wed, Aug 18, 2010 at 18:32, Johannes Sixt <j6t@kdbg.org> wrote:\n> On Mittwoch, 18. August 2010, Ævar Arnfjörð Bjarmason wrote:\n>> According to some further research at least FreeBSD and NetBSD have\n>> copied this GNU extension. You may find their versions easier to\n>> integrate.\n>\n> We already have a GNU fnmatch in compat/fnmatch.\n\nDo you have any plan to deal with this? I currently have this\nmonkeypatch to build on Solaris:\n\n    diff --git a/Makefile b/Makefile\n    index 62d526a..079fae5 100644\n    --- a/Makefile\n    +++ b/Makefile\n    @@ -863,2 +863,4 @@ endif\n     ifeq ($(uname_S),SunOS)\n    +       COMPAT_OBJS = compat/fnmatch/fnmatch.o\n    +       COMPAT_CFLAGS = -Icompat -Icompat/fnmatch\n            NEEDS_SOCKET = YesPlease\n\nOne way to deal with it would be a new NONGNU_FNMATCH=UnfortunatelyYes\nflag, or the fnmatch_icase() suggestion above which we could bundle\nand always use. But having next build on systems without GNU\nextensions would be preferrable.\n"},{"id":"149332","messageId":"4C7BC344.9020500@workspacewhiz.com","threadId":"24755","inReplyTo":"AANLkTimtmudtWccRS==LrO_JrPmAJ7HzA6CU0ALbDZcV@mail.gmail.com","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Joshua Jensen","fromEmail":"jjensen@workspacewhiz.com","sentAt":"2010-08-30T14:42:12Z","receivedAt":"2010-08-30T14:42:12Z","isPatch":true,"sender":{"key":"jjensen@workspacewhiz.com","avatar":"https://avatars.githubusercontent.com/u/111687?v=4"},"body":"  ----- Original Message -----\nFrom: Ævar Arnfjörð Bjarmason\nDate: 8/29/2010 1:39 PM\n> On Wed, Aug 18, 2010 at 18:32, Johannes Sixt<j6t@kdbg.org>  wrote:\n>> On Mittwoch, 18. August 2010, Ævar Arnfjörð Bjarmason wrote:\n>>> According to some further research at least FreeBSD and NetBSD have\n>>> copied this GNU extension. You may find their versions easier to\n>>> integrate.\n>> We already have a GNU fnmatch in compat/fnmatch.\n> Do you have any plan to deal with this? I currently have this\n> monkeypatch to build on Solaris:\n>\n>      diff --git a/Makefile b/Makefile\n>      index 62d526a..079fae5 100644\n>      --- a/Makefile\n>      +++ b/Makefile\n>      @@ -863,2 +863,4 @@ endif\n>       ifeq ($(uname_S),SunOS)\n>      +       COMPAT_OBJS = compat/fnmatch/fnmatch.o\n>      +       COMPAT_CFLAGS = -Icompat -Icompat/fnmatch\n>              NEEDS_SOCKET = YesPlease\n>\n> One way to deal with it would be a new NONGNU_FNMATCH=UnfortunatelyYes\n> flag, or the fnmatch_icase() suggestion above which we could bundle\n> and always use. But having next build on systems without GNU\n> extensions would be preferrable.\nI am going to deal with this, but I haven't been around.  I hope for \nsome time this week.\n\nShort of duplicating fnmatch's code and renaming the function, I am not \nsure how to make this play nice on all systems.  You added COMPAT_OBJS \nabove, but I think there is no linker guarantee it will pick up \ncompat/fnmatch/fnmatch.o over the C runtime version?  Perhaps the \nmakefile is architected to do so.\n\nThe safest alternative is to allocate character buffers, lowercase the \nfilename and match arguments into those buffers, and pass them off to \nfnmatch without any special flags.  I don't like the idea of a double \nmemory allocation/free combo per each call to this function, but it \nwould work.  Is anyone opposed to this approach?\n\nJosh\n"},{"id":"149333","messageId":"AANLkTikbLtfx6xL6K32o_AXqY+qeqKANN5n2g0oYPoi6@mail.gmail.com","threadId":"24755","inReplyTo":"4C7BC344.9020500@workspacewhiz.com","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-30T14:51:26Z","receivedAt":"2010-08-30T14:51:26Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Mon, Aug 30, 2010 at 14:42, Joshua Jensen <jjensen@workspacewhiz.com> wrote:\n>  ----- Original Message -----\n> From: Ævar Arnfjörð Bjarmason\n> Date: 8/29/2010 1:39 PM\n>>\n>> On Wed, Aug 18, 2010 at 18:32, Johannes Sixt<j6t@kdbg.org>  wrote:\n>>>\n>>> On Mittwoch, 18. August 2010, Ævar Arnfjörð Bjarmason wrote:\n>>>>\n>>>> According to some further research at least FreeBSD and NetBSD have\n>>>> copied this GNU extension. You may find their versions easier to\n>>>> integrate.\n>>>\n>>> We already have a GNU fnmatch in compat/fnmatch.\n>>\n>> Do you have any plan to deal with this? I currently have this\n>> monkeypatch to build on Solaris:\n>>\n>>     diff --git a/Makefile b/Makefile\n>>     index 62d526a..079fae5 100644\n>>     --- a/Makefile\n>>     +++ b/Makefile\n>>     @@ -863,2 +863,4 @@ endif\n>>      ifeq ($(uname_S),SunOS)\n>>     +       COMPAT_OBJS = compat/fnmatch/fnmatch.o\n>>     +       COMPAT_CFLAGS = -Icompat -Icompat/fnmatch\n>>             NEEDS_SOCKET = YesPlease\n>>\n>> One way to deal with it would be a new NONGNU_FNMATCH=UnfortunatelyYes\n>> flag, or the fnmatch_icase() suggestion above which we could bundle\n>> and always use. But having next build on systems without GNU\n>> extensions would be preferrable.\n>\n> I am going to deal with this, but I haven't been around.  I hope for some\n> time this week.\n\nSure, no rush. I was just wondering whether you had some plan for it,\nor whether I should submit a patch to use the fallback on\ne.g. Solaris.\n\n> Short of duplicating fnmatch's code and renaming the function, I am not sure\n> how to make this play nice on all systems.\n\nI don't think duplicating the GNU (or *BSD) version into a\ncompat/fnmatch.c would be a bad thing. See e.g. compat/snprintf.c.\n\n> You added COMPAT_OBJS above, but I think there is no linker\n> guarantee it will pick up compat/fnmatch/fnmatch.o over the C\n> runtime version?  Perhaps the makefile is architected to do so.\n\nIt's probably just an artifact of how the Solaris linker works, it\ndoesn't go through the trouble of undefining an existing fnmatch\nsymbol or anything.\n\n> The safest alternative is to allocate character buffers, lowercase the\n> filename and match arguments into those buffers, and pass them off to\n> fnmatch without any special flags.  I don't like the idea of a double memory\n> allocation/free combo per each call to this function, but it would work.  Is\n> anyone opposed to this approach?\n\nJust using the GNU extension and providing a fallback is probably\ncleaner and easier to maintain.\n"},{"id":"149334","messageId":"20100830145220.GI2315@burratino","threadId":"24755","inReplyTo":"4C7BC344.9020500@workspacewhiz.com","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-30T14:52:20Z","receivedAt":"2010-08-30T14:52:20Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Joshua Jensen wrote:\n\n> I don't like the idea of\n> a double memory allocation/free combo per each call to this\n> function, but it would work.\n\nMaybe the caller can provide a (strbuf) buffer?\n"},{"id":"149336","messageId":"20100830150513.GJ2315@burratino","threadId":"24755","inReplyTo":"AANLkTikbLtfx6xL6K32o_AXqY+qeqKANN5n2g0oYPoi6@mail.gmail.com","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-30T15:05:13Z","receivedAt":"2010-08-30T15:05:13Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Ævar Arnfjörð Bjarmason wrote:\n\n> I don't think duplicating the GNU (or *BSD) version into a\n> compat/fnmatch.c would be a bad thing. See e.g. compat/snprintf.c.\n\nMaybe meanwhile someone (I guess that means \"I\") can ask around about\nFNM_CASEFOLD going into posix.  I like to imagine the compat/\ndirectory shrinking over time.\n\n>> You added COMPAT_OBJS above, but I think there is no linker\n>> guarantee it will pick up compat/fnmatch/fnmatch.o over the C\n>> runtime version?  Perhaps the makefile is architected to do so.\n>\n> It's probably just an artifact of how the Solaris linker works\n\nIsn't the portable way to do something like\n\n #define fnmatch gitfnmatch\n\nin fnmatch.h?\n\nMeanwhile I guess that no other system header includes fnmatch.h, but\nif that were to happen, there would be preprocessor symbol conflicts.\nSo on systems with fnmatch, ideally one would want to do something\nlike this:\n\n #include <fnmatch.h>\n #ifdef FNMATCH_LACKS_CASEFOLD\n # undef FNM_PATHNAME\n # define FNM_PATHNAME\t(1 << 0)\n # define FNM_CASEFOLD\t(1 << 4)\n # define fnmatch gitfnmatch\n extern int fnmatch(const char *pattern, const char *name, int flags);\n #endif\n"},{"id":"149354","messageId":"201008302040.10399.j6t@kdbg.org","threadId":"24755","inReplyTo":"4C7BC344.9020500@workspacewhiz.com","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-08-30T18:40:10Z","receivedAt":"2010-08-30T18:40:10Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Montag, 30. August 2010, Joshua Jensen wrote:\n> From: Ævar Arnfjörð Bjarmason\n> >      +       COMPAT_OBJS = compat/fnmatch/fnmatch.o\n> >      +       COMPAT_CFLAGS = -Icompat -Icompat/fnmatch\n...\n> You added COMPAT_OBJS\n> above, but I think there is no linker guarantee it will pick up\n> compat/fnmatch/fnmatch.o over the C runtime version?\n\nThe way linkers work ensures that git code picks up the compat version when \ndefined this way.\n\n-- Hannes\n"},{"id":"149356","messageId":"AANLkTi=CeeBkHZgCOtACxCtWoab6Q+3Jwtx327KDFjqh@mail.gmail.com","threadId":"24755","inReplyTo":"201008302040.10399.j6t@kdbg.org","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-30T19:57:29Z","receivedAt":"2010-08-30T19:57:29Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Mon, Aug 30, 2010 at 18:40, Johannes Sixt <j6t@kdbg.org> wrote:\n> On Montag, 30. August 2010, Joshua Jensen wrote:\n>> From: Ævar Arnfjörð Bjarmason\n>> >      +       COMPAT_OBJS = compat/fnmatch/fnmatch.o\n>> >      +       COMPAT_CFLAGS = -Icompat -Icompat/fnmatch\n> ...\n>> You added COMPAT_OBJS\n>> above, but I think there is no linker guarantee it will pick up\n>> compat/fnmatch/fnmatch.o over the C runtime version?\n>\n> The way linkers work ensures that git code picks up the compat version when\n> defined this way.\n\nSo why does e.g. compat/snprintf.c need to \"#undef snprintf\" before\ndefining it again?\n"},{"id":"149358","messageId":"201008302213.07279.j6t@kdbg.org","threadId":"24755","inReplyTo":"AANLkTi=CeeBkHZgCOtACxCtWoab6Q+3Jwtx327KDFjqh@mail.gmail.com","subject":"Re: [PATCH 1/6] Add string comparison functions that respect the ignore_case variable.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-08-30T20:13:07Z","receivedAt":"2010-08-30T20:13:07Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Montag, 30. August 2010, Ævar Arnfjörð Bjarmason wrote:\n> So why does e.g. compat/snprintf.c need to \"#undef snprintf\" before\n> defining it again?\n\nBecause the implementation of the compat snprintf uses the system's snprintf.\n\nThere are other cases, like e.g., pread, where it would not be necessary to \n#define pread git_pread.\n\n-- Hannes\n"}]}