summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0a9b88b)
raw | patch | inline | side by side (parent: 0a9b88b)
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | |
Sat, 22 Mar 2008 16:35:59 +0000 (09:35 -0700) | ||
committer | Junio 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>
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 | patch | blob | history | |
unpack-trees.h | patch | blob | history |
diff --git a/unpack-trees.c b/unpack-trees.c
index bf7d8f6c5c8962f1f0e872a4f9b79f28dd0cc876..95d3413ae5bfa905deb7c836fe0633cd0a9942df 100644 (file)
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -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.
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
diff --git a/unpack-trees.h b/unpack-trees.h
index ad8cc65d68cf8c69b47970bb6bc239ad7acdf722..d436d6ced9939beeb4599dc8fddebe0890e55db8 100644 (file)
--- a/unpack-trees.h
+++ b/unpack-trees.h
void *unpack_data;
struct index_state *dst_index;
- const struct index_state *src_index;
+ struct index_state *src_index;
struct index_state result;
};