From: Junio C Hamano Date: Sat, 20 May 2006 08:55:25 +0000 (-0700) Subject: Merge branch 'jc/dirwalk-n-cache-tree' into next X-Git-Tag: v1.4.1-rc1~79 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/7f2d5cb53185e4734d37a7789f3870bd81963cf3?hp=-c Merge branch 'jc/dirwalk-n-cache-tree' into next * jc/dirwalk-n-cache-tree: Signed-off-by: Junio C Hamano --- 7f2d5cb53185e4734d37a7789f3870bd81963cf3 diff --combined read-tree.c index a3ada55c15,99e7c75044..55f7f87133 --- a/read-tree.c +++ b/read-tree.c @@@ -22,7 -22,6 +22,7 @@@ static int trivial_merges_only = 0 static int aggressive = 0; static int verbose_update = 0; static volatile int progress_update = 0; +static const char *prefix = NULL; static int head_idx = -1; static int merge_size = 0; @@@ -371,8 -370,7 +371,8 @@@ static int unpack_trees(merge_fn_t fn posns[i] = ((struct tree *) posn->item)->entries; posn = posn->next; } - if (unpack_trees_rec(posns, len, "", fn, &indpos)) + if (unpack_trees_rec(posns, len, prefix ? prefix : "", + fn, &indpos)) return -1; } @@@ -721,28 -719,6 +721,28 @@@ static int twoway_merge(struct cache_en return deleted_entry(oldtree, current); } +/* + * Bind merge. + * + * Keep the index entries at stage0, collapse stage1 but make sure + * stage0 does not have anything there. + */ +static int bind_merge(struct cache_entry **src) +{ + struct cache_entry *old = src[0]; + struct cache_entry *a = src[1]; + + if (merge_size != 1) + return error("Cannot do a bind merge of %d trees\n", + merge_size); + if (a && old) + die("Entry '%s' overlaps. Cannot bind.", a->name); + if (!a) + return keep_entry(old); + else + return merged_entry(a, NULL); +} + /* * One-way merge. * @@@ -758,10 -734,8 +758,10 @@@ static int oneway_merge(struct cache_en return error("Cannot do a oneway merge of %d trees", merge_size); - if (!a) + if (!a) { + invalidate_ce_path(old); return deleted_entry(old, old); + } if (old && same(old, a)) { if (reset) { struct stat st; @@@ -801,7 -775,7 +801,7 @@@ static void prime_cache_tree_rec(struc { struct tree_entry_list *ent; int cnt; - + memcpy(it->sha1, tree->object.sha1, 20); for (cnt = 0, ent = tree->entries; ent; ent = ent->next) { if (!ent->directory) @@@ -830,7 -804,7 +830,7 @@@ static void prime_cache_tree(void } -static const char read_tree_usage[] = "git-read-tree ( | -m [--aggressive] [-u | -i] [ []])"; +static const char read_tree_usage[] = "git-read-tree ( | [[-m [--aggressive] | --reset | --prefix=] [-u | -i]] [ []])"; static struct cache_file cache_file; @@@ -875,24 -849,9 +875,24 @@@ int main(int argc, char **argv continue; } + /* "--prefix=/" means keep the current index + * entries and put the entries from the tree under the + * given subdirectory. + */ + if (!strncmp(arg, "--prefix=", 9)) { + if (stage || merge || prefix) + usage(read_tree_usage); + prefix = arg + 9; + merge = 1; + stage = 1; + if (read_cache_unmerged()) + die("you need to resolve your current index first"); + continue; + } + /* This differs from "-m" in that we'll silently ignore unmerged entries */ if (!strcmp(arg, "--reset")) { - if (stage || merge) + if (stage || merge || prefix) usage(read_tree_usage); reset = 1; merge = 1; @@@ -913,7 -872,7 +913,7 @@@ /* "-m" stands for "merge", meaning we start in stage 1 */ if (!strcmp(arg, "-m")) { - if (stage || merge) + if (stage || merge || prefix) usage(read_tree_usage); if (read_cache_unmerged()) die("you need to resolve your current index first"); @@@ -935,31 -894,12 +935,31 @@@ if ((update||index_only) && !merge) usage(read_tree_usage); + if (prefix) { + int pfxlen = strlen(prefix); + int pos; + if (prefix[pfxlen-1] != '/') + die("prefix must end with /"); + if (stage != 2) + die("binding merge takes only one tree"); + pos = cache_name_pos(prefix, pfxlen); + if (0 <= pos) + die("corrupt index file"); + pos = -pos-1; + if (pos < active_nr && + !strncmp(active_cache[pos]->name, prefix, pfxlen)) + die("subdirectory '%s' already exists.", prefix); + pos = cache_name_pos(prefix, pfxlen-1); + if (0 <= pos) + die("file '%.*s' already exists.", pfxlen-1, prefix); + } + if (merge) { if (stage < 2) die("just how do you expect me to merge %d trees?", stage-1); switch (stage - 1) { case 1: - fn = oneway_merge; + fn = prefix ? bind_merge : oneway_merge; break; case 2: fn = twoway_merge;