On Fri, Nov 24, 2017 at 2:59 PM, Elijah Newren <newren@xxxxxxxxx> wrote: > In commit ae352c7f3 (merge-recursive.c: fix case-changing merge bug, > 2014-05-01), it was observed that removing files could be problematic on > case insensitive file systems, because we could end up removing files > that differed in case only rather than deleting the intended file -- > something that happened when files were renamed on one branch in a way > that differed only in case. To avoid that problem, that commit added > logic to avoid removing files other than the one intended, rejecting the > removal if the files differed only in case. > > Unfortunately, the logic it used didn't fully implement that condition as > stated above; instead it merely checked that a case-insensitive lookup of > the file that was requested resulted in finding a file in the index at > stage 0, not that the file found in the index actually differed in case. > Alternatively, one could view the implementation as making an implicit > assumption that the file we actually wanted to remove would never appear > in the index with a stage of 0, and thus that if we found a file with our > lookup, that it had to be a different file (but different in case only). > > The net result of this implementation is that it can ignore more requests > than it should, leaving a file around in the working copy that should > have been removed. Make sure that the file found in the index actually > differs in case before silently ignoring the request to remove the file. > > --- Missing sign-off. > diff --git a/merge-recursive.c b/merge-recursive.c > index b48b15a6f..100fb913f 100644 > --- a/merge-recursive.c > +++ b/merge-recursive.c > @@ -646,7 +646,7 @@ static int remove_file(struct merge_options *o, int clean, > if (ignore_case) { > struct cache_entry *ce; > ce = cache_file_exists(path, strlen(path), ignore_case); > - if (ce && ce_stage(ce) == 0) > + if (ce && ce_stage(ce) == 0 && strcmp(path, ce->name)) > return 0; > } > if (remove_path(path)) > -- > 2.11.0