From 96872bc200c41407607019c1f0fb005840f576a2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 21 Mar 2008 13:16:24 -0700 Subject: Move name hashing functions into a file of its own It's really totally separate functionality, and if we want to start doing case-insensitive hash lookups, I'd rather do it when it's separated out. It also renames "remove_index_entry()" to "remove_name_hash()", because that really describes the thing better. It doesn't actually remove the index entry, that's done by "remove_index_entry_at()", which is something very different, despite the similarity in names. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- cache.h | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 2a1e7ec6b2..2afc788f74 100644 --- a/cache.h +++ b/cache.h @@ -153,20 +153,6 @@ static inline void copy_cache_entry(struct cache_entry *dst, struct cache_entry dst->ce_flags = (dst->ce_flags & ~CE_STATE_MASK) | state; } -/* - * We don't actually *remove* it, we can just mark it invalid so that - * we won't find it in lookups. - * - * Not only would we have to search the lists (simple enough), but - * we'd also have to rehash other hash buckets in case this makes the - * hash bucket empty (common). So it's much better to just mark - * it. - */ -static inline void remove_index_entry(struct cache_entry *ce) -{ - ce->ce_flags |= CE_UNHASHED; -} - static inline unsigned create_ce_flags(size_t len, unsigned stage) { if (len >= CE_NAMEMASK) @@ -241,6 +227,23 @@ struct index_state { extern struct index_state the_index; +/* Name hashing */ +extern void add_name_hash(struct index_state *istate, struct cache_entry *ce); +/* + * We don't actually *remove* it, we can just mark it invalid so that + * we won't find it in lookups. + * + * Not only would we have to search the lists (simple enough), but + * we'd also have to rehash other hash buckets in case this makes the + * hash bucket empty (common). So it's much better to just mark + * it. + */ +static inline void remove_name_hash(struct cache_entry *ce) +{ + ce->ce_flags |= CE_UNHASHED; +} + + #ifndef NO_THE_INDEX_COMPATIBILITY_MACROS #define active_cache (the_index.cache) #define active_nr (the_index.cache_nr) -- cgit v1.2.1 From df292c791ab790340cc9e3577a073bcb9d1900ea Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 21 Mar 2008 15:53:00 -0700 Subject: Make "index_name_exists()" return the cache_entry it found This allows verify_absent() in unpack_trees() to use the hash chains rather than looking it up using the binary search. Perhaps more importantly, it's also going to be useful for the next phase, where we actually start looking at the cache entry when we do case-insensitive lookups and checking the result. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- cache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 2afc788f74..76d95d2c81 100644 --- a/cache.h +++ b/cache.h @@ -353,7 +353,7 @@ extern int write_index(const struct index_state *, int newfd); extern int discard_index(struct index_state *); extern int unmerged_index(const struct index_state *); extern int verify_path(const char *path); -extern int index_name_exists(struct index_state *istate, const char *name, int namelen); +extern struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen); extern int index_name_pos(const struct index_state *, const char *name, int namelen); #define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */ #define ADD_CACHE_OK_TO_REPLACE 2 /* Ok to replace file/directory */ -- cgit v1.2.1 From cd2fef59edf72a1d9792d9cb72aae1e6f6c7b1d4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 21 Mar 2008 15:55:19 -0700 Subject: Make hash_name_lookup able to do case-independent lookups Right now nobody uses it, but "index_name_exists()" gets a flag so you can enable it on a case-by-case basis. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- cache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 76d95d2c81..a9ddaa1240 100644 --- a/cache.h +++ b/cache.h @@ -264,7 +264,7 @@ static inline void remove_name_hash(struct cache_entry *ce) #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL) #define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options)) #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options)) -#define cache_name_exists(name, namelen) index_name_exists(&the_index, (name), (namelen)) +#define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase)) #endif enum object_type { @@ -353,7 +353,7 @@ extern int write_index(const struct index_state *, int newfd); extern int discard_index(struct index_state *); extern int unmerged_index(const struct index_state *); extern int verify_path(const char *path); -extern struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen); +extern struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int igncase); extern int index_name_pos(const struct index_state *, const char *name, int namelen); #define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */ #define ADD_CACHE_OK_TO_REPLACE 2 /* Ok to replace file/directory */ -- cgit v1.2.1 From 0a9b88b7dee70bd36d35b7857640a18ee3adeef1 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 21 Mar 2008 16:52:46 -0700 Subject: Add 'core.ignorecase' option ..and start using it for directory entry traversal (ie "git status" will not consider entries that match an existing entry case-insensitively to be a new file) Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- cache.h | 1 + 1 file changed, 1 insertion(+) (limited to 'cache.h') diff --git a/cache.h b/cache.h index a9ddaa1240..9bce723bb8 100644 --- a/cache.h +++ b/cache.h @@ -407,6 +407,7 @@ extern int delete_ref(const char *, const unsigned char *sha1); extern int trust_executable_bit; extern int quote_path_fully; extern int has_symlinks; +extern int ignore_case; extern int assume_unchanged; extern int prefer_symlink_refs; extern int log_all_ref_updates; -- cgit v1.2.1 From 1102952b45dde09d73445aa2284bcb592362fa23 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 22 Mar 2008 14:22:44 -0700 Subject: Make git-add behave more sensibly in a case-insensitive environment This expands on the previous patch, and allows "git add" to sanely handle a filename that has changed case, keeping the case in the index constant, and avoiding aliases. In particular, if you have an index entry called "File", but the checked-out tree is case-corrupted and has an entry called "file" instead, doing a git add . (or naming "file" explicitly) will automatically notice that we have an alias, and will replace the name "file" with the existing index capitalization (ie "File"). However, if we actually have *both* a file called "File" and one called "file", and they don't have the same lstat() information (ie we're on a case-sensitive filesystem but have the "core.ignorecase" flag set), we will error out if we try to add them both. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- cache.h | 1 + 1 file changed, 1 insertion(+) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 9bce723bb8..81727e4afe 100644 --- a/cache.h +++ b/cache.h @@ -133,6 +133,7 @@ struct cache_entry { #define CE_UPDATE (0x10000) #define CE_REMOVE (0x20000) #define CE_UPTODATE (0x40000) +#define CE_ADDED (0x80000) #define CE_HASHED (0x100000) #define CE_UNHASHED (0x200000) -- cgit v1.2.1