From: Junio C Hamano Date: Tue, 30 May 2017 02:16:45 +0000 (+0900) Subject: Merge branch 'dt/unpack-save-untracked-cache-extension' X-Git-Tag: v2.14.0-rc0~136 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/fa0624f79f9d5765d09598b003124b3cf0b9acdb?ds=inline;hp=-c Merge branch 'dt/unpack-save-untracked-cache-extension' When "git checkout", "git merge", etc. manipulates the in-core index, various pieces of information in the index extensions are discarded from the original state, as it is usually not the case that they are kept up-to-date and in-sync with the operation on the main index. The untracked cache extension is copied across these operations now, which would speed up "git status" (as long as the cache is properly invalidated). * dt/unpack-save-untracked-cache-extension: unpack-trees: preserve index extensions --- fa0624f79f9d5765d09598b003124b3cf0b9acdb diff --combined cache.h index d1f2c5c088,d41336dfd5..ae4c45d379 --- a/cache.h +++ b/cache.h @@@ -597,6 -597,7 +597,7 @@@ extern int read_index_unmerged(struct i #define CLOSE_LOCK (1 << 1) extern int write_locked_index(struct index_state *, struct lock_file *lock, unsigned flags); extern int discard_index(struct index_state *); + extern void move_index_extensions(struct index_state *dst, struct index_state *src); extern int unmerged_index(const struct index_state *); extern int verify_path(const char *path); extern int strcmp_offset(const char *s1, const char *s2, size_t *first_change); @@@ -1479,18 -1480,18 +1480,18 @@@ struct date_mode #define DATE_MODE(t) date_mode_from_type(DATE_##t) struct date_mode *date_mode_from_type(enum date_mode_type type); -const char *show_date(unsigned long time, int timezone, const struct date_mode *mode); -void show_date_relative(unsigned long time, int tz, const struct timeval *now, +const char *show_date(timestamp_t time, int timezone, const struct date_mode *mode); +void show_date_relative(timestamp_t time, int tz, const struct timeval *now, struct strbuf *timebuf); int parse_date(const char *date, struct strbuf *out); -int parse_date_basic(const char *date, unsigned long *timestamp, int *offset); -int parse_expiry_date(const char *date, unsigned long *timestamp); +int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset); +int parse_expiry_date(const char *date, timestamp_t *timestamp); void datestamp(struct strbuf *out); #define approxidate(s) approxidate_careful((s), NULL) -unsigned long approxidate_careful(const char *, int *); -unsigned long approxidate_relative(const char *date, const struct timeval *now); +timestamp_t approxidate_careful(const char *, int *); +timestamp_t approxidate_relative(const char *date, const struct timeval *now); void parse_date_format(const char *format, struct date_mode *mode); -int date_overflows(unsigned long date); +int date_overflows(timestamp_t date); #define IDENT_STRICT 1 #define IDENT_NO_DATE 2 @@@ -2198,8 -2199,8 +2199,8 @@@ struct commit_list int try_merge_command(const char *strategy, size_t xopts_nr, const char **xopts, struct commit_list *common, const char *head_arg, struct commit_list *remotes); -int checkout_fast_forward(const unsigned char *from, - const unsigned char *to, +int checkout_fast_forward(const struct object_id *from, + const struct object_id *to, int overwrite_ignore); diff --combined read-cache.c index 22ab8b5b61,79827a4d71..92eb15c000 --- a/read-cache.c +++ b/read-cache.c @@@ -1877,9 -1877,15 +1877,9 @@@ int discard_index(struct index_state *i { int i; - for (i = 0; i < istate->cache_nr; i++) { - if (istate->cache[i]->index && - istate->split_index && - istate->split_index->base && - istate->cache[i]->index <= istate->split_index->base->cache_nr && - istate->cache[i] == istate->split_index->base->cache[istate->cache[i]->index - 1]) - continue; + unshare_split_index(istate, 1); + for (i = 0; i < istate->cache_nr; i++) free(istate->cache[i]); - } resolve_undo_clear_index(istate); istate->cache_nr = 0; istate->cache_changed = 0; @@@ -2191,7 -2197,6 +2191,7 @@@ static int do_write_index(struct index_ int entries = istate->cache_nr; struct stat st; struct strbuf previous_name_buf = STRBUF_INIT, *previous_name; + int drop_cache_tree = 0; for (i = removed = extended = 0; i < entries; i++) { if (cache[i]->ce_flags & CE_REMOVE) @@@ -2242,8 -2247,6 +2242,8 @@@ warning(msg, ce->name); else return error(msg, ce->name); + + drop_cache_tree = 1; } if (ce_write_entry(&c, newfd, ce, previous_name) < 0) return -1; @@@ -2262,7 -2265,7 +2262,7 @@@ if (err) return -1; } - if (!strip_extensions && istate->cache_tree) { + if (!strip_extensions && !drop_cache_tree && istate->cache_tree) { struct strbuf sb = STRBUF_INIT; cache_tree_write(&sb, istate->cache_tree); @@@ -2625,3 -2628,9 +2625,9 @@@ void stat_validity_update(struct stat_v fill_stat_data(sv->sd, &st); } } + + void move_index_extensions(struct index_state *dst, struct index_state *src) + { + dst->untracked = src->untracked; + src->untracked = NULL; + } diff --combined unpack-trees.c index c312c2cd3a,17117bd0fd..d38c37e38c --- a/unpack-trees.c +++ b/unpack-trees.c @@@ -252,18 -252,14 +252,18 @@@ static int check_submodule_move_head(co const char *new_id, struct unpack_trees_options *o) { + unsigned flags = SUBMODULE_MOVE_HEAD_DRY_RUN; const struct submodule *sub = submodule_from_ce(ce); if (!sub) return 0; + if (o->reset) + flags |= SUBMODULE_MOVE_HEAD_FORCE; + switch (sub->update_strategy.type) { case SM_UPDATE_UNSPECIFIED: case SM_UPDATE_CHECKOUT: - if (submodule_move_head(ce->name, old_id, new_id, SUBMODULE_MOVE_HEAD_DRY_RUN)) + if (submodule_move_head(ce->name, old_id, new_id, flags)) return o->gently ? -1 : add_rejected_path(o, ERROR_WOULD_LOSE_SUBMODULE, ce->name); return 0; @@@ -312,7 -308,6 +312,7 @@@ static void unlink_entry(const struct c case SM_UPDATE_CHECKOUT: case SM_UPDATE_REBASE: case SM_UPDATE_MERGE: + /* state.force is set at the caller. */ submodule_move_head(ce->name, "HEAD", NULL, SUBMODULE_MOVE_HEAD_FORCE); break; @@@ -1073,7 -1068,7 +1073,7 @@@ static int clear_ce_flags_dir(struct ca struct cache_entry **cache_end; int dtype = DT_DIR; int ret = is_excluded_from_list(prefix->buf, prefix->len, - basename, &dtype, el); + basename, &dtype, el, &the_index); int rc; strbuf_addch(prefix, '/'); @@@ -1176,7 -1171,7 +1176,7 @@@ static int clear_ce_flags_1(struct cach /* Non-directory */ dtype = ce_to_dtype(ce); ret = is_excluded_from_list(ce->name, ce_namelen(ce), - name, &dtype, el); + name, &dtype, el, &the_index); if (ret < 0) ret = defval; if (ret > 0) @@@ -1256,7 -1251,7 +1256,7 @@@ int unpack_trees(unsigned len, struct t o->skip_sparse_checkout = 1; if (!o->skip_sparse_checkout) { char *sparse = git_pathdup("info/sparse-checkout"); - if (add_excludes_from_file_to_list(sparse, "", 0, &el, 0) < 0) + if (add_excludes_from_file_to_list(sparse, "", 0, &el, NULL) < 0) o->skip_sparse_checkout = 1; else o->el = ⪙ @@@ -1396,6 -1391,7 +1396,7 @@@ WRITE_TREE_SILENT | WRITE_TREE_REPAIR); } + move_index_extensions(&o->result, o->dst_index); discard_index(o->dst_index); *o->dst_index = o->result; } else { @@@ -1597,7 -1593,7 +1598,7 @@@ static int verify_clean_subdirectory(co memset(&d, 0, sizeof(d)); if (o->dir) d.exclude_per_dir = o->dir->exclude_per_dir; - i = read_directory(&d, pathbuf, namelen+1, NULL); + i = read_directory(&d, &the_index, pathbuf, namelen+1, NULL); if (i) return o->gently ? -1 : add_rejected_path(o, ERROR_NOT_UPTODATE_DIR, ce->name); @@@ -1639,7 -1635,7 +1640,7 @@@ static int check_ok_to_remove(const cha return 0; if (o->dir && - is_excluded(o->dir, name, &dtype)) + is_excluded(o->dir, &the_index, name, &dtype)) /* * ce->name is explicitly excluded, so it is Ok to * overwrite it.