From: Junio C Hamano Date: Thu, 23 Apr 2009 02:36:19 +0000 (-0700) Subject: Merge branch 'jc/maint-read-tree-multi' X-Git-Tag: v1.6.3-rc2~14 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/ea0b767c1ea66f687e58a9fcff45a5a518e699c3?ds=inline;hp=-c Merge branch 'jc/maint-read-tree-multi' * jc/maint-read-tree-multi: checkout branch: prime cache-tree fully read-tree -m A B: prime cache-tree from the switched-to tree Move prime_cache_tree() to cache-tree.c read-tree A B: do not corrupt cache-tree --- ea0b767c1ea66f687e58a9fcff45a5a518e699c3 diff --combined builtin-checkout.c index 383598c9bf,efa1ebfe07..15f0c32c7a --- a/builtin-checkout.c +++ b/builtin-checkout.c @@@ -5,6 -5,7 +5,7 @@@ #include "commit.h" #include "tree.h" #include "tree-walk.h" + #include "cache-tree.h" #include "unpack-trees.h" #include "dir.h" #include "run-command.h" @@@ -178,7 -179,7 +179,7 @@@ static int checkout_merged(int pos, str /* * NEEDSWORK: * There is absolutely no reason to write this as a blob object - * and create a phoney cache entry just to leak. This hack is + * and create a phony cache entry just to leak. This hack is * primarily to get to the write_entry() machinery that massages * the contents to work-tree format and writes out which only * allows it for a cache entry. The code in write_entry() needs @@@ -292,8 -293,6 +293,8 @@@ static void show_local_changes(struct o init_revisions(&rev, NULL); rev.abbrev = 0; rev.diffopt.output_format |= DIFF_FORMAT_NAME_STATUS; + if (diff_setup_done(&rev.diffopt) < 0) + die("diff_setup_done failed"); add_pending_object(&rev, head, NULL); run_diff_index(&rev, 0); } @@@ -350,11 -349,16 +351,11 @@@ struct branch_info static void setup_branch_path(struct branch_info *branch) { struct strbuf buf = STRBUF_INIT; - int ret; - if ((ret = interpret_nth_last_branch(branch->name, &buf)) - && ret == strlen(branch->name)) { + strbuf_branchname(&buf, branch->name); + if (strcmp(buf.buf, branch->name)) branch->name = xstrdup(buf.buf); - strbuf_splice(&buf, 0, 0, "refs/heads/", 11); - } else { - strbuf_addstr(&buf, "refs/heads/"); - strbuf_addstr(&buf, branch->name); - } + strbuf_splice(&buf, 0, 0, "refs/heads/", 11); branch->path = strbuf_detach(&buf, NULL); } @@@ -364,14 -368,17 +365,17 @@@ static int merge_working_tree(struct ch int ret; struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); int newfd = hold_locked_index(lock_file, 1); + int reprime_cache_tree = 0; if (read_cache() < 0) return error("corrupt index file"); + cache_tree_free(&active_cache_tree); if (opts->force) { ret = reset_tree(new->commit->tree, opts, 1); if (ret) return ret; + reprime_cache_tree = 1; } else { struct tree_desc trees[2]; struct tree *tree; @@@ -399,7 -406,7 +403,7 @@@ topts.verbose_update = !opts->quiet; topts.fn = twoway_merge; topts.dir = xcalloc(1, sizeof(*topts.dir)); - topts.dir->show_ignored = 1; + topts.dir->flags |= DIR_SHOW_IGNORED; topts.dir->exclude_per_dir = ".gitignore"; tree = parse_tree_indirect(old->commit->object.sha1); init_tree_desc(&trees[0], tree->buffer, tree->size); @@@ -407,7 -414,9 +411,9 @@@ init_tree_desc(&trees[1], tree->buffer, tree->size); ret = unpack_trees(2, trees, &topts); - if (ret == -1) { + if (ret != -1) { + reprime_cache_tree = 1; + } else { /* * Unpack couldn't do a trivial merge; either * give up or do a real merge, depending on @@@ -451,6 -460,8 +457,8 @@@ } } + if (reprime_cache_tree) + prime_cache_tree(&active_cache_tree, new->commit->tree); if (write_cache(newfd, active_cache, active_nr) || commit_locked_index(lock_file)) die("unable to write new index file"); @@@ -550,8 -561,8 +558,8 @@@ static int switch_branches(struct check if (!old.commit && !opts->force) { if (!opts->quiet) { - fprintf(stderr, "warning: You appear to be on a branch yet to be born.\n"); - fprintf(stderr, "warning: Forcing checkout of %s.\n", new->name); + warning("You appear to be on a branch yet to be born."); + warning("Forcing checkout of %s.", new->name); } opts->force = 1; } @@@ -730,11 -741,12 +738,11 @@@ no_reference if (opts.new_branch) { struct strbuf buf = STRBUF_INIT; - strbuf_addstr(&buf, "refs/heads/"); - strbuf_addstr(&buf, opts.new_branch); + if (strbuf_check_branch_ref(&buf, opts.new_branch)) + die("git checkout: we do not like '%s' as a branch name.", + opts.new_branch); if (!get_sha1(buf.buf, rev)) die("git checkout: branch %s already exists", opts.new_branch); - if (check_ref_format(buf.buf)) - die("git checkout: we do not like '%s' as a branch name.", opts.new_branch); strbuf_release(&buf); } diff --combined builtin-read-tree.c index 8e0273864d,391d709704..82e25eaa07 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@@ -29,41 -29,6 +29,6 @@@ static int list_tree(unsigned char *sha return 0; } - static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree) - { - struct tree_desc desc; - struct name_entry entry; - int cnt; - - hashcpy(it->sha1, tree->object.sha1); - init_tree_desc(&desc, tree->buffer, tree->size); - cnt = 0; - while (tree_entry(&desc, &entry)) { - if (!S_ISDIR(entry.mode)) - cnt++; - else { - struct cache_tree_sub *sub; - struct tree *subtree = lookup_tree(entry.sha1); - if (!subtree->object.parsed) - parse_tree(subtree); - sub = cache_tree_sub(it, entry.path); - sub->cache_tree = cache_tree(); - prime_cache_tree_rec(sub->cache_tree, subtree); - cnt += sub->cache_tree->entry_count; - } - } - it->entry_count = cnt; - } - - static void prime_cache_tree(void) - { - if (!nr_trees) - return; - active_cache_tree = cache_tree(); - prime_cache_tree_rec(active_cache_tree, trees[0]); - - } - static const char read_tree_usage[] = "git read-tree ( | [[-m [--trivial] [--aggressive] | --reset | --prefix=] [-u | -i]] [--exclude-per-directory=] [--index-output=] [ []])"; static struct lock_file lock_file; @@@ -170,7 -135,7 +135,7 @@@ int cmd_read_tree(int argc, const char die("more than one --exclude-per-directory are given."); dir = xcalloc(1, sizeof(*opts.dir)); - dir->show_ignored = 1; + dir->flags |= DIR_SHOW_IGNORED; dir->exclude_per_dir = arg + 24; opts.dir = dir; /* We do not need to nor want to do read-directory @@@ -211,7 -176,6 +176,6 @@@ case 3: default: opts.fn = threeway_merge; - cache_tree_free(&active_cache_tree); break; } @@@ -221,6 -185,7 +185,7 @@@ opts.head_idx = 1; } + cache_tree_free(&active_cache_tree); for (i = 0; i < nr_trees; i++) { struct tree *tree = trees[i]; parse_tree(tree); @@@ -234,11 -199,14 +199,14 @@@ * "-m ent" or "--reset ent" form), we can obtain a fully * valid cache-tree because the index must match exactly * what came from the tree. + * + * The same holds true if we are switching between two trees + * using read-tree -m A B. The index must match B after that. */ - if (nr_trees && !opts.prefix && (!opts.merge || (stage == 2))) { - cache_tree_free(&active_cache_tree); - prime_cache_tree(); - } + if (nr_trees == 1 && !opts.prefix) + prime_cache_tree(&active_cache_tree, trees[0]); + else if (nr_trees == 2 && opts.merge) + prime_cache_tree(&active_cache_tree, trees[1]); if (write_cache(newfd, active_cache, active_nr) || commit_locked_index(&lock_file))