Make branch merging aware of underlying case-insensitive filsystems
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Sat, 22 Mar 2008 16:35:59 +0000 (09:35 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 9 Apr 2008 08:22:25 +0000 (01:22 -0700)
If we find an unexpected file, see if that filename perhaps exists in a
case-insensitive way in the index, and whether the file matches that. If
so, ignore it as a known pre-existing file of a different name.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
unpack-trees.c
unpack-trees.h

index bf7d8f6c5c8962f1f0e872a4f9b79f28dd0cc876..95d3413ae5bfa905deb7c836fe0633cd0a9942df 100644 (file)
@@ -520,6 +520,22 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
        return cnt;
 }
 
+/*
+ * This gets called when there was no index entry for the tree entry 'dst',
+ * but we found a file in the working tree that 'lstat()' said was fine,
+ * and we're on a case-insensitive filesystem.
+ *
+ * See if we can find a case-insensitive match in the index that also
+ * matches the stat information, and assume it's that other file!
+ */
+static int icase_exists(struct unpack_trees_options *o, struct cache_entry *dst, struct stat *st)
+{
+       struct cache_entry *src;
+
+       src = index_name_exists(o->src_index, dst->name, ce_namelen(dst), 1);
+       return src && !ie_match_stat(o->src_index, src, st, CE_MATCH_IGNORE_VALID);
+}
+
 /*
  * We do not want to remove or overwrite a working tree file that
  * is not tracked, unless it is ignored.
@@ -540,6 +556,16 @@ static int verify_absent(struct cache_entry *ce, const char *action,
                int dtype = ce_to_dtype(ce);
                struct cache_entry *result;
 
+               /*
+                * It may be that the 'lstat()' succeeded even though
+                * target 'ce' was absent, because there is an old
+                * entry that is different only in case..
+                *
+                * Ignore that lstat() if it matches.
+                */
+               if (ignore_case && icase_exists(o, ce, &st))
+                       return 0;
+
                if (o->dir && excluded(o->dir, ce->name, &dtype))
                        /*
                         * ce->name is explicitly excluded, so it is Ok to
index ad8cc65d68cf8c69b47970bb6bc239ad7acdf722..d436d6ced9939beeb4599dc8fddebe0890e55db8 100644 (file)
@@ -31,7 +31,7 @@ struct unpack_trees_options {
        void *unpack_data;
 
        struct index_state *dst_index;
-       const struct index_state *src_index;
+       struct index_state *src_index;
        struct index_state result;
 };