Skip to content

Commit 2ba3d5d

Browse files
committed
Merge branch 'jc/maint-checkout-keep-remove' into maint
* jc/maint-checkout-keep-remove: checkout: do not lose staged removal
2 parents 01409bb + 5521883 commit 2ba3d5d

File tree

5 files changed

+24
-2
lines changed

5 files changed

+24
-2
lines changed

Documentation/git-read-tree.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,10 @@ Here are the "carry forward" rules:
160160
0 nothing nothing nothing (does not happen)
161161
1 nothing nothing exists use M
162162
2 nothing exists nothing remove path from index
163-
3 nothing exists exists use M
163+
3 nothing exists exists, use M if "initial checkout"
164+
H == M keep index otherwise
165+
exists fail
166+
H != M
164167

165168
clean I==H I==M
166169
------------------
@@ -207,6 +210,12 @@ you picked it up via e-mail in a patch form), `git diff-index
207210
merge, but it would not show in `git diff-index --cached $M`
208211
output after two-tree merge.
209212

213+
Case #3 is slightly tricky and needs explanation. The result from this
214+
rule logically should be to remove the path if the user staged the removal
215+
of the path and then swiching to a new branch. That however will prevent
216+
the initial checkout from happening, so the rule is modified to use M (new
217+
tree) only when the contents of the index is empty. Otherwise the removal
218+
of the path is kept as long as $H and $M are the same.
210219

211220
3-Way Merge
212221
~~~~~~~~~~~

builtin-checkout.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ static int merge_working_tree(struct checkout_opts *opts,
269269
}
270270

271271
/* 2-way merge to the new branch */
272+
topts.initial_checkout = (!active_nr &&
273+
(old->commit == new->commit));
272274
topts.update = 1;
273275
topts.merge = 1;
274276
topts.gently = opts->merge;

builtin-read-tree.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
206206
break;
207207
case 2:
208208
opts.fn = twoway_merge;
209+
opts.initial_checkout = !active_nr;
209210
break;
210211
case 3:
211212
default:

unpack-trees.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -941,8 +941,17 @@ int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o)
941941
return -1;
942942
}
943943
}
944-
else if (newtree)
944+
else if (newtree) {
945+
if (oldtree && !o->initial_checkout) {
946+
/*
947+
* deletion of the path was staged;
948+
*/
949+
if (same(oldtree, newtree))
950+
return 1;
951+
return reject_merge(oldtree, o);
952+
}
945953
return merged_entry(newtree, current, o);
954+
}
946955
return deleted_entry(oldtree, current, o);
947956
}
948957

unpack-trees.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct unpack_trees_options {
2626
verbose_update:1,
2727
aggressive:1,
2828
skip_unmerged:1,
29+
initial_checkout:1,
2930
gently:1;
3031
const char *prefix;
3132
int pos;

0 commit comments

Comments
 (0)