Junio C Hamano <gitster@xxxxxxxxx> writes: > Jing Xue <jingxue@xxxxxxxxxxxxxxxxx> writes: > ... >> In Git 1.6.0 the following sequence: >> ... >> The deletion of 2.txt appears lost during 'checkout -b foo', while the >> modification and addition were both brought over. Is it a bug? > > This behaviour is unchanged since early June 2005. > > http://thread.gmane.org/gmane.comp.version-control.git/4641/focus=4646 > > This is exactly the case marked as *0*, which both Linus and I said "it > feels somewhat wrong but otherwise we cannot start from an empty index". > > We may want to do better this time around, though. Try this patch. Documentation/git-read-tree.txt | 11 ++++++++++- builtin-checkout.c | 1 + builtin-read-tree.c | 1 + unpack-trees.c | 11 ++++++++++- unpack-trees.h | 1 + 5 files changed, 23 insertions(+), 2 deletions(-) diff --git c/Documentation/git-read-tree.txt i/Documentation/git-read-tree.txt index 6f4b9b0..24155ab 100644 --- c/Documentation/git-read-tree.txt +++ i/Documentation/git-read-tree.txt @@ -160,7 +160,10 @@ Here are the "carry forward" rules: 0 nothing nothing nothing (does not happen) 1 nothing nothing exists use M 2 nothing exists nothing remove path from index - 3 nothing exists exists use M + 3 nothing exists exists, use M if index is empty + H == M keep index otherwise + exists fail + H != M clean I==H I==M ------------------ @@ -207,6 +210,12 @@ you picked it up via e-mail in a patch form), `git diff-index merge, but it would not show in `git diff-index --cached $M` output after two-tree merge. +Case #3 is slightly tricky and needs explanation. The result from this +rule logically should be to remove the path if the user staged the removal +of the path and then swiching to a new branch. That however will prevent +the initial checkout from happening, so the rule is modified to use M (new +tree) only when the contents of the index is empty. Otherwise the removal +of the path is kept as long as $H and $M are the same. 3-Way Merge ~~~~~~~~~~~ diff --git c/builtin-checkout.c i/builtin-checkout.c index efdb1e0..c73a815 100644 --- c/builtin-checkout.c +++ i/builtin-checkout.c @@ -242,6 +242,7 @@ static int merge_working_tree(struct checkout_opts *opts, } /* 2-way merge to the new branch */ + topts.index_was_empty = !active_nr; topts.update = 1; topts.merge = 1; topts.gently = opts->merge; diff --git c/builtin-read-tree.c i/builtin-read-tree.c index dddc304..41ece57 100644 --- c/builtin-read-tree.c +++ i/builtin-read-tree.c @@ -160,6 +160,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) die("you need to resolve your current index first"); stage = 1; opts.merge = 1; + opts.index_was_empty = !active_nr; continue; } diff --git c/unpack-trees.c i/unpack-trees.c index ef21c62..43ff477 100644 --- c/unpack-trees.c +++ i/unpack-trees.c @@ -941,8 +941,17 @@ int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o) return -1; } } - else if (newtree) + else if (newtree) { + if (oldtree && !o->index_was_empty) { + /* + * deletion of the path was staged; + */ + if (same(oldtree, newtree)) + return 1; + return reject_merge(oldtree, o); + } return merged_entry(newtree, current, o); + } return deleted_entry(oldtree, current, o); } diff --git c/unpack-trees.h i/unpack-trees.h index 94e5672..61d82ce 100644 --- c/unpack-trees.h +++ i/unpack-trees.h @@ -26,6 +26,7 @@ struct unpack_trees_options { verbose_update:1, aggressive:1, skip_unmerged:1, + index_was_empty:1, gently:1; const char *prefix; int pos; -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html