From: Junio C Hamano Date: Thu, 27 Feb 2014 22:01:40 +0000 (-0800) Subject: Merge branch 'nd/reset-intent-to-add' X-Git-Tag: v2.0.0-rc0~153 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/8336832ad99832d21e5ee588bd3d03369048c05a?hp=-c Merge branch 'nd/reset-intent-to-add' * nd/reset-intent-to-add: reset: support "--mixed --intent-to-add" mode --- 8336832ad99832d21e5ee588bd3d03369048c05a diff --combined cache.h index 5994f7a203,8f35d12a7e..9f15744218 --- a/cache.h +++ b/cache.h @@@ -3,7 -3,7 +3,7 @@@ #include "git-compat-util.h" #include "strbuf.h" -#include "hash.h" +#include "hashmap.h" #include "advice.h" #include "gettext.h" #include "convert.h" @@@ -130,12 -130,12 +130,12 @@@ struct stat_data }; struct cache_entry { + struct hashmap_entry ent; struct stat_data ce_stat_data; unsigned int ce_mode; unsigned int ce_flags; unsigned int ce_namelen; unsigned char sha1[20]; - struct cache_entry *next; char name[FLEX_ARRAY]; /* more */ }; @@@ -159,6 -159,7 +159,6 @@@ #define CE_ADDED (1 << 19) #define CE_HASHED (1 << 20) -#define CE_UNHASHED (1 << 21) #define CE_WT_REMOVE (1 << 22) /* remove in work directory */ #define CE_CONFLICTED (1 << 23) @@@ -194,18 -195,17 +194,18 @@@ struct pathspec * Copy the sha1 and stat state of a cache entry from one to * another. But we never change the name, or the hash state! */ -#define CE_STATE_MASK (CE_HASHED | CE_UNHASHED) static inline void copy_cache_entry(struct cache_entry *dst, const struct cache_entry *src) { - unsigned int state = dst->ce_flags & CE_STATE_MASK; + unsigned int state = dst->ce_flags & CE_HASHED; /* Don't copy hash chain and name */ - memcpy(dst, src, offsetof(struct cache_entry, next)); + memcpy(&dst->ce_stat_data, &src->ce_stat_data, + offsetof(struct cache_entry, name) - + offsetof(struct cache_entry, ce_stat_data)); /* Restore the hash state */ - dst->ce_flags = (dst->ce_flags & ~CE_STATE_MASK) | state; + dst->ce_flags = (dst->ce_flags & ~CE_HASHED) | state; } static inline unsigned create_ce_flags(unsigned stage) @@@ -277,8 -277,8 +277,8 @@@ struct index_state struct cache_time timestamp; unsigned name_hash_initialized : 1, initialized : 1; - struct hash_table name_hash; - struct hash_table dir_hash; + struct hashmap name_hash; + struct hashmap dir_hash; }; extern struct index_state the_index; @@@ -316,6 -316,7 +316,6 @@@ extern void free_name_hash(struct index #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options)) #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen)) #define cache_file_exists(name, namelen, igncase) index_file_exists(&the_index, (name), (namelen), (igncase)) -#define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase)) #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen)) #define resolve_undo_clear() resolve_undo_clear_index(&the_index) #define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at) @@@ -466,6 -467,7 +466,6 @@@ extern int unmerged_index(const struct extern int verify_path(const char *path); extern struct cache_entry *index_dir_exists(struct index_state *istate, const char *name, int namelen); extern struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int igncase); -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 */ @@@ -485,8 -487,9 +485,9 @@@ extern int remove_file_from_index(struc #define ADD_CACHE_IMPLICIT_DOT 32 /* internal to "git add -u/-A" */ extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags); extern int add_file_to_index(struct index_state *, const char *path, int flags); -extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh); +extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, unsigned int refresh_options); extern int ce_same_name(const struct cache_entry *a, const struct cache_entry *b); + extern void set_object_name_for_intent_to_add_entry(struct cache_entry *ce); extern int index_name_is_other(const struct index_state *, const char *, int); extern void *read_blob_data_from_index(struct index_state *, const char *, unsigned long *); @@@ -496,13 -499,11 +497,13 @@@ #define CE_MATCH_RACY_IS_DIRTY 02 /* do stat comparison even if CE_SKIP_WORKTREE is true */ #define CE_MATCH_IGNORE_SKIP_WORKTREE 04 +/* ignore non-existent files during stat update */ +#define CE_MATCH_IGNORE_MISSING 0x08 +/* enable stat refresh */ +#define CE_MATCH_REFRESH 0x10 extern int ie_match_stat(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int); extern int ie_modified(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int); -extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec); - #define HASH_WRITE_OBJECT 1 #define HASH_FORMAT_CHECK 2 extern int index_fd(unsigned char *sha1, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags); diff --combined read-cache.c index 29c1047eeb,f0b1eaddab..6d8ee3a792 --- a/read-cache.c +++ b/read-cache.c @@@ -15,8 -15,7 +15,8 @@@ #include "strbuf.h" #include "varint.h" -static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really); +static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, + unsigned int options); /* Mask for the name length in ce_flags in the on-disk index */ @@@ -48,7 -47,6 +48,7 @@@ static void replace_index_entry(struct struct cache_entry *old = istate->cache[nr]; remove_name_hash(istate, old); + free(old); set_index_entry(istate, nr, ce); istate->cache_changed = 1; } @@@ -60,7 -58,7 +60,7 @@@ void rename_index_entry_at(struct index new = xmalloc(cache_entry_size(namelen)); copy_cache_entry(new, old); - new->ce_flags &= ~CE_STATE_MASK; + new->ce_flags &= ~CE_HASHED; new->ce_namelen = namelen; memcpy(new->name, new_name, namelen + 1); @@@ -480,7 -478,6 +480,7 @@@ int remove_index_entry_at(struct index_ record_resolve_undo(istate, ce); remove_name_hash(istate, ce); + free(ce); istate->cache_changed = 1; istate->cache_nr--; if (pos >= istate->cache_nr) @@@ -502,10 -499,8 +502,10 @@@ void remove_marked_cache_entries(struc unsigned int i, j; for (i = j = 0; i < istate->cache_nr; i++) { - if (ce_array[i]->ce_flags & CE_REMOVE) + if (ce_array[i]->ce_flags & CE_REMOVE) { remove_name_hash(istate, ce_array[i]); + free(ce_array[i]); + } else ce_array[j++] = ce_array[i]; } @@@ -584,7 -579,7 +584,7 @@@ static struct cache_entry *create_alias return new; } - static void record_intent_to_add(struct cache_entry *ce) + void set_object_name_for_intent_to_add_entry(struct cache_entry *ce) { unsigned char sha1[20]; if (write_sha1_file("", 0, blob_type, sha1)) @@@ -670,7 -665,7 +670,7 @@@ int add_to_index(struct index_state *is if (index_path(ce->sha1, path, st, HASH_WRITE_OBJECT)) return error("unable to index file %s", path); } else - record_intent_to_add(ce); + set_object_name_for_intent_to_add_entry(ce); if (ignore_case && alias && different_name(ce, alias)) ce = create_alias_ce(ce, alias); @@@ -701,7 -696,7 +701,7 @@@ int add_file_to_index(struct index_stat struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, - int refresh) + unsigned int refresh_options) { int size, len; struct cache_entry *ce; @@@ -721,7 -716,10 +721,7 @@@ ce->ce_namelen = len; ce->ce_mode = create_ce_mode(mode); - if (refresh) - return refresh_cache_entry(ce, 0); - - return ce; + return refresh_cache_entry(ce, refresh_options); } int ce_same_name(const struct cache_entry *a, const struct cache_entry *b) @@@ -730,6 -728,11 +730,6 @@@ return ce_namelen(b) == len && !memcmp(a->name, b->name, len); } -int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec) -{ - return match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL); -} - /* * We fundamentally don't like some paths: we don't want * dot or dot-dot anywhere, and for obvious reasons don't @@@ -1026,12 -1029,10 +1026,12 @@@ static struct cache_entry *refresh_cach struct stat st; struct cache_entry *updated; int changed, size; + int refresh = options & CE_MATCH_REFRESH; int ignore_valid = options & CE_MATCH_IGNORE_VALID; int ignore_skip_worktree = options & CE_MATCH_IGNORE_SKIP_WORKTREE; + int ignore_missing = options & CE_MATCH_IGNORE_MISSING; - if (ce_uptodate(ce)) + if (!refresh || ce_uptodate(ce)) return ce; /* @@@ -1049,8 -1050,6 +1049,8 @@@ } if (lstat(ce->name, &st) < 0) { + if (ignore_missing && errno == ENOENT) + return ce; if (err) *err = errno; return NULL; @@@ -1128,9 -1127,7 +1128,9 @@@ int refresh_index(struct index_state *i int ignore_submodules = (flags & REFRESH_IGNORE_SUBMODULES) != 0; int first = 1; int in_porcelain = (flags & REFRESH_IN_PORCELAIN); - unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0; + unsigned int options = (CE_MATCH_REFRESH | + (really ? CE_MATCH_IGNORE_VALID : 0) | + (not_new ? CE_MATCH_IGNORE_MISSING : 0)); const char *modified_fmt; const char *deleted_fmt; const char *typechange_fmt; @@@ -1152,7 -1149,8 +1152,7 @@@ if (ignore_submodules && S_ISGITLINK(ce->ce_mode)) continue; - if (pathspec && - !match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen)) + if (pathspec && !ce_path_match(ce, pathspec, seen)) filtered = 1; if (ce_stage(ce)) { @@@ -1178,6 -1176,8 +1178,6 @@@ if (!new) { const char *fmt; - if (not_new && cache_errno == ENOENT) - continue; if (really && cache_errno == EINVAL) { /* If we are doing --really-refresh that * means the index is not valid anymore. @@@ -1207,10 -1207,9 +1207,10 @@@ return has_errors; } -static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really) +static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, + unsigned int options) { - return refresh_cache_ent(&the_index, ce, really, NULL, NULL); + return refresh_cache_ent(&the_index, ce, options, NULL, NULL); } @@@ -1895,7 -1894,7 +1895,7 @@@ int read_index_unmerged(struct index_st new_ce->ce_mode = ce->ce_mode; if (add_index_entry(istate, new_ce, 0)) return error("%s: cannot drop to stage #0", - ce->name); + new_ce->name); i = index_name_pos(istate, new_ce->name, len); } return unmerged;