On Sat, Jul 28, 2018 at 12:48:57AM -0400, Jeff King wrote: > On Sat, Jul 28, 2018 at 06:45:43AM +0200, Duy Nguyen wrote: > > > > I agree throwing a real exception would be bad. But how about detecting > > > the problem and trying our best to keep the repo in somewhat usable > > > state like this? > > > > > > This patch uses sparse checkout to hide all those paths that we fail > > > to checkout, so you can still have a clean worktree to do things, as > > > long as you don't touch those paths. > > > > Side note. There may still be problems with this patch. Let's use > > vim-colorschemes.git as an example, which has darkBlue.vim and > > darkblue.vim. > > > > Say we have checked out darkBlue.vim and hidden darkblue.vim. When you > > update darkBlue.vim on worktree and then update the index, are we sure > > we will update darkBlue.vim entry and not (hidden) darkblue.vim? I am > > not sure. I don't think our lookup function is prepared to deal with > > this. Maybe it's best to hide both of them. > > It might be enough to just issue a warning and give an advise() hint > that tells the user what's going on. Then they can decide what to do > (hide both paths, or just work in the index, or move to a different fs, > or complain to upstream). Yeah that may be the best option. Something like this perhaps? Not sure how much detail the advice should be here. -- 8< -- diff --git a/builtin/clone.c b/builtin/clone.c index 1d939af9d8..b47ad5877b 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -711,6 +711,30 @@ static void update_head(const struct ref *our, const struct ref *remote, } } +static int has_duplicate_icase_entries(struct index_state *istate) +{ + struct string_list list = STRING_LIST_INIT_NODUP; + int i; + int found = 0; + + for (i = 0; i < istate->cache_nr; i++) + string_list_append(&list, istate->cache[i]->name); + + list.cmp = strcasecmp; + string_list_sort(&list); + + for (i = 1; i < list.nr; i++) { + if (strcasecmp(list.items[i-1].string, + list.items[i].string)) + continue; + found = 1; + break; + } + string_list_clear(&list, 0); + + return found; +} + static int checkout(int submodule_progress) { struct object_id oid; @@ -761,6 +785,11 @@ static int checkout(int submodule_progress) if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK)) die(_("unable to write new index file")); + if (ignore_case && has_duplicate_icase_entries(&the_index)) + warning(_("This repository has paths that only differ in case\n" + "and you have a case-insenitive filesystem which will\n" + "cause problems.")); + err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1), oid_to_hex(&oid), "1", NULL); -- 8< --