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< --