On 2014-03-01 03.42, Lee Hopkins wrote: > I went ahead and took a stab at a solution. My solution is more > aggressive than a warning, I actually prevent the creation of > ambiguous refs. My changes are also in refs.c, which may not be > appropriate, but it seemed like the natural place. > > I have never contributed to Git (in fact this is my first dive into > the source) and my C is a bit rusty, so bear with me, this is just a > suggestion: > > --- > refs.c | 31 ++++++++++++++++++++++++------- > 1 files changed, 24 insertions(+), 7 deletions(-) > > diff --git a/refs.c b/refs.c > index 89228e2..12ccdac 100644 > --- a/refs.c > +++ b/refs.c > @@ -359,14 +359,24 @@ struct string_slice { > const char *str; > }; > > +static int ref_entry_ncmp(const void *key_, const void *ent_, int > (*cmp_fn)(const char *, const char *, size_t)) > +{ > + const struct string_slice *key = key_; > + const struct ref_entry *ent = *(const struct ref_entry * const *)ent_; > + int cmp = cmp_fn(key->str, ent->name, key->len); > + if (cmp) > + return cmp; > + return '\0' - (unsigned char)ent->name[key->len]; > +} > + > static int ref_entry_cmp_sslice(const void *key_, const void *ent_) > { > - const struct string_slice *key = key_; > - const struct ref_entry *ent = *(const struct ref_entry * const *)ent_; > - int cmp = strncmp(key->str, ent->name, key->len); > - if (cmp) > - return cmp; > - return '\0' - (unsigned char)ent->name[key->len]; > + return ref_entry_ncmp(key_, ent_, strncmp); > +} > + > +static int ref_entry_casecmp_sslice(const void *key_, const void *ent_) > +{ > + return ref_entry_ncmp(key_, ent_, strncasecmp); > } > > /* > @@ -378,6 +388,7 @@ static int search_ref_dir(struct ref_dir *dir, > const char *refname, size_t len) > { > struct ref_entry **r; > struct string_slice key; > + int (*cmp_fn)(const void *, const void *); > > if (refname == NULL || !dir->nr) > return -1; > @@ -385,8 +396,14 @@ static int search_ref_dir(struct ref_dir *dir, > const char *refname, size_t len) > sort_ref_dir(dir); > key.len = len; > key.str = refname; > + > + if(ignore_case) Only looking at ignore_case here closes the door for people who have a branch "foo" and "Foo" at the same time. (Which means that they are carefully running git pack-refs) How about something like this: + if (refs_ignore_case < 0) + refs_ignore_case = ignore_case; + if (refs_ignore_case) (And then we need the diff further down on top of this.) (And of course Documentation/config.txt) The main motivation is that you can set refs.ignorecase == true on e.g. Linux, to prevent to have branches "Foo" and "foo" at the same time, which gives problems when pulling into e.g. Windows/Mac OS > + cmp_fn = ref_entry_casecmp_sslice; > + else > + cmp_fn = ref_entry_cmp_sslice; > + > r = bsearch(&key, dir->entries, dir->nr, sizeof(*dir->entries), > - ref_entry_cmp_sslice); > + cmp_fn); > > if (r == NULL) > return -1; > -- diff --git a/builtin/init-db.c b/builtin/init-db.c index c7c76bb..dbfc61f 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -288,8 +288,10 @@ 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)) { + git_config_set("core.ignorecase", "true"); + git_config_set("refs.ignorecase", "true"); + } probe_utf8_pathname_composition(path, len); } diff --git a/config.c b/config.c index d969a5a..8f1ec81 100644 --- a/config.c +++ b/config.c @@ -698,6 +698,11 @@ static int git_default_core_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "refs.ignorecase")) { + refs_ignore_case = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "core.attributesfile")) return git_config_pathname(&git_attributes_file, var, value); diff --git a/environment.c b/environment.c index 4a3437d..2eced48 100644 --- a/environment.c +++ b/environment.c @@ -18,6 +18,7 @@ int check_stat = 1; int has_symlinks = 1; int minimum_abbrev = 4, default_abbrev = 7; int ignore_case; +int refs_ignore_case = -1; int assume_unchanged; int prefer_symlink_refs; int is_bare_repository_cfg = -1; /* unspecified */ -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html