diff options
-rw-r--r-- | Documentation/git-read-tree.txt | 11 | ||||
-rw-r--r-- | builtin-checkout.c | 2 | ||||
-rw-r--r-- | builtin-read-tree.c | 1 | ||||
-rw-r--r-- | unpack-trees.c | 11 | ||||
-rw-r--r-- | unpack-trees.h | 1 |
5 files changed, 24 insertions, 2 deletions
diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index 6f4b9b017f..309deac23b 100644 --- a/Documentation/git-read-tree.txt +++ b/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 "initial checkout" + 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 a/builtin-checkout.c b/builtin-checkout.c index f6f8f086de..774f29992a 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -242,6 +242,8 @@ static int merge_working_tree(struct checkout_opts *opts, } /* 2-way merge to the new branch */ + topts.initial_checkout = (!active_nr && + (old->commit == new->commit)); topts.update = 1; topts.merge = 1; topts.gently = opts->merge; diff --git a/builtin-read-tree.c b/builtin-read-tree.c index dddc3044b8..362216b272 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -206,6 +206,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) break; case 2: opts.fn = twoway_merge; + opts.initial_checkout = !active_nr; break; case 3: default: diff --git a/unpack-trees.c b/unpack-trees.c index ef21c62195..e59d144d28 100644 --- a/unpack-trees.c +++ b/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->initial_checkout) { + /* + * 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 a/unpack-trees.h b/unpack-trees.h index 94e567265a..0d26f3d73e 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -26,6 +26,7 @@ struct unpack_trees_options { verbose_update:1, aggressive:1, skip_unmerged:1, + initial_checkout:1, gently:1; const char *prefix; int pos; |