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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html