From: Junio C Hamano Date: Sun, 16 Oct 2011 03:46:36 +0000 (-0700) Subject: Merge branch 'jc/diff-index-unpack' into maint X-Git-Tag: v1.7.7.1~22 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=fc26f57b847b86ba330ea543a6dfc86a10d4cce3;hp=-c;p=git.git Merge branch 'jc/diff-index-unpack' into maint * jc/diff-index-unpack: diff-index: pass pathspec down to unpack-trees machinery unpack-trees: allow pruning with pathspec traverse_trees(): allow pruning with pathspec --- fc26f57b847b86ba330ea543a6dfc86a10d4cce3 diff --combined diff-lib.c index f8454dd29,12760b422..ebe751e72 --- a/diff-lib.c +++ b/diff-lib.c @@@ -379,8 -379,7 +379,8 @@@ static void do_oneway_diff(struct unpac if (cached && idx && ce_stage(idx)) { struct diff_filepair *pair; pair = diff_unmerge(&revs->diffopt, idx->name); - fill_filespec(pair->one, idx->sha1, idx->ce_mode); + if (tree) + fill_filespec(pair->one, tree->sha1, tree->ce_mode); return; } @@@ -434,30 -433,26 +434,30 @@@ static int oneway_diff(struct cache_ent if (tree == o->df_conflict_entry) tree = NULL; - if (ce_path_match(idx ? idx : tree, &revs->prune_data)) + if (ce_path_match(idx ? idx : tree, &revs->prune_data)) { do_oneway_diff(o, idx, tree); + if (diff_can_quit_early(&revs->diffopt)) { + o->exiting_early = 1; + return -1; + } + } return 0; } -int run_diff_index(struct rev_info *revs, int cached) +static int diff_cache(struct rev_info *revs, + const unsigned char *tree_sha1, + const char *tree_name, + int cached) { - struct object *ent; struct tree *tree; - const char *tree_name; - struct unpack_trees_options opts; struct tree_desc t; + struct unpack_trees_options opts; - ent = revs->pending.objects[0].item; - tree_name = revs->pending.objects[0].name; - tree = parse_tree_indirect(ent->sha1); + tree = parse_tree_indirect(tree_sha1); if (!tree) - return error("bad tree object %s", tree_name); - + return error("bad tree object %s", + tree_name ? tree_name : sha1_to_hex(tree_sha1)); memset(&opts, 0, sizeof(opts)); opts.head_idx = 1; opts.index_only = cached; @@@ -468,17 -463,10 +468,18 @@@ opts.unpack_data = revs; opts.src_index = &the_index; opts.dst_index = NULL; + opts.pathspec = &revs->diffopt.pathspec; init_tree_desc(&t, tree->buffer, tree->size); - if (unpack_trees(1, &t, &opts)) + return unpack_trees(1, &t, &opts); +} + +int run_diff_index(struct rev_info *revs, int cached) +{ + struct object_array_entry *ent; + + ent = revs->pending.objects; + if (diff_cache(revs, ent->item->sha1, ent->name, cached)) exit(128); diff_set_mnemonic_prefix(&revs->diffopt, "c/", cached ? "i/" : "w/"); @@@ -490,13 -478,53 +491,13 @@@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) { - struct tree *tree; struct rev_info revs; - int i; - struct cache_entry **dst; - struct cache_entry *last = NULL; - struct unpack_trees_options opts; - struct tree_desc t; - - /* - * This is used by git-blame to run diff-cache internally; - * it potentially needs to repeatedly run this, so we will - * start by removing the higher order entries the last round - * left behind. - */ - dst = active_cache; - for (i = 0; i < active_nr; i++) { - struct cache_entry *ce = active_cache[i]; - if (ce_stage(ce)) { - if (last && !strcmp(ce->name, last->name)) - continue; - cache_tree_invalidate_path(active_cache_tree, - ce->name); - last = ce; - ce->ce_flags |= CE_REMOVE; - } - *dst++ = ce; - } - active_nr = dst - active_cache; init_revisions(&revs, NULL); init_pathspec(&revs.prune_data, opt->pathspec.raw); - tree = parse_tree_indirect(tree_sha1); - if (!tree) - die("bad tree object %s", sha1_to_hex(tree_sha1)); - - memset(&opts, 0, sizeof(opts)); - opts.head_idx = 1; - opts.index_only = 1; - opts.diff_index_cached = !DIFF_OPT_TST(opt, FIND_COPIES_HARDER); - opts.merge = 1; - opts.fn = oneway_diff; - opts.unpack_data = &revs; - opts.src_index = &the_index; - opts.dst_index = &the_index; + revs.diffopt = *opt; - init_tree_desc(&t, tree->buffer, tree->size); - if (unpack_trees(1, &t, &opts)) + if (diff_cache(&revs, tree_sha1, NULL, 1)) exit(128); return 0; } diff --combined unpack-trees.c index cc616c3f9,d5ec463e0..670b46473 --- a/unpack-trees.c +++ b/unpack-trees.c @@@ -444,6 -444,7 +444,7 @@@ static int traverse_trees_recursive(in newinfo = *info; newinfo.prev = info; + newinfo.pathspec = info->pathspec; newinfo.name = *p; newinfo.pathlen += tree_entry_len(p->path, p->sha1) + 1; newinfo.conflicts |= df_conflicts; @@@ -593,7 -594,7 +594,7 @@@ static int unpack_nondirectories(int n static int unpack_failed(struct unpack_trees_options *o, const char *message) { discard_index(&o->result); - if (!o->gently) { + if (!o->gently && !o->exiting_early) { if (message) return error("%s", message); return -1; @@@ -1040,6 -1041,7 +1041,7 @@@ int unpack_trees(unsigned len, struct t info.fn = unpack_callback; info.data = o; info.show_all_errors = o->show_all_errors; + info.pathspec = o->pathspec; if (o->prefix) { /* @@@ -1133,8 -1135,6 +1135,8 @@@ return_failed display_error_msgs(o); mark_all_ce_unused(o->src_index); ret = unpack_failed(o, NULL); + if (o->exiting_early) + ret = 0; goto done; } @@@ -1168,22 -1168,11 +1170,22 @@@ static int verify_uptodate_1(struct cac { struct stat st; - if (o->index_only || (!((ce->ce_flags & CE_VALID) || ce_skip_worktree(ce)) && (o->reset || ce_uptodate(ce)))) + if (o->index_only) + return 0; + + /* + * CE_VALID and CE_SKIP_WORKTREE cheat, we better check again + * if this entry is truly up-to-date because this file may be + * overwritten. + */ + if ((ce->ce_flags & CE_VALID) || ce_skip_worktree(ce)) + ; /* keep checking */ + else if (o->reset || ce_uptodate(ce)) return 0; if (!lstat(ce->name, &st)) { - unsigned changed = ie_match_stat(o->src_index, ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE); + int flags = CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE; + unsigned changed = ie_match_stat(o->src_index, ce, &st, flags); if (!changed) return 0; /* diff --combined unpack-trees.h index 799894830,b7fed7e6e..5e432f576 --- a/unpack-trees.h +++ b/unpack-trees.h @@@ -46,12 -46,12 +46,13 @@@ struct unpack_trees_options debug_unpack, skip_sparse_checkout, gently, + exiting_early, show_all_errors, dry_run; const char *prefix; int cache_bottom; struct dir_struct *dir; + struct pathspec *pathspec; merge_fn_t fn; const char *msgs[NB_UNPACK_TREES_ERROR_TYPES]; /*