diff options
author | Max Kirillov <max@max630.net> | 2018-07-10 19:17:48 (GMT) |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2018-07-11 16:35:41 (GMT) |
commit | b33fdfc34cda95f92cc7a50e5c81b87f8ee65eef (patch) | |
tree | dd902336f607c413310baae3d40bf51d158081cd | |
parent | 53f9a3e157dbbc901a02ac2c73346d375e24978c (diff) | |
download | git-b33fdfc34cda95f92cc7a50e5c81b87f8ee65eef.zip git-b33fdfc34cda95f92cc7a50e5c81b87f8ee65eef.tar.gz git-b33fdfc34cda95f92cc7a50e5c81b87f8ee65eef.tar.bz2 |
unpack-trees: do not fail reset because of unmerged skipped entry
After modify/delete merge conflict happens in a file skipped by sparse
checkout, "git reset --merge", which implements the "--abort" actions,
and "git reset --hard" fail with message "Entry * not uptodate. Cannot
update sparse checkout."
As explained in [1], the up-to-date checker mistakenly treats conflicted
entry which does not exist in HEAD as still skipped by sparse checkout.
Use the fix suggested in [1]. Also, add test case which verifies the
issue is fixed.
[1] https://public-inbox.org/git/20180616051444.GA29754@duynguyen.home/
Signed-off-by: Duy Nguyen <pclouds@gmail.com>
Signed-off-by: Max Kirillov <max@max630.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rwxr-xr-x | t/t3035-merge-sparse.sh | 59 | ||||
-rw-r--r-- | unpack-trees.c | 2 |
2 files changed, 60 insertions, 1 deletions
diff --git a/t/t3035-merge-sparse.sh b/t/t3035-merge-sparse.sh new file mode 100755 index 0000000..0c0b433 --- /dev/null +++ b/t/t3035-merge-sparse.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +test_description='merge with sparse files' + +. ./test-lib.sh + +# test_file $filename $content +test_file () { + echo "$2" > "$1" && + git add "$1" +} + +# test_commit_this $message_and_tag +test_commit_this () { + git commit -m "$1" && + git tag "$1" +} + +test_expect_success 'setup' ' + : >empty && + test_file checked-out init && + test_file modify_delete modify_delete_init && + test_commit_this init && + test_file modify_delete modify_delete_theirs && + test_commit_this theirs && + git reset --hard init && + git rm modify_delete && + test_commit_this ours && + git config core.sparseCheckout true && + echo "/checked-out" >.git/info/sparse-checkout && + git reset --hard && + ! git merge theirs +' + +test_expect_success 'reset --hard works after the conflict' ' + git reset --hard +' + +test_expect_success 'is reset properly' ' + git status --porcelain -- modify_delete >out && + test_cmp empty out && + test_path_is_missing modify_delete +' + +test_expect_success 'setup: conflict back' ' + ! git merge theirs +' + +test_expect_success 'Merge abort works after the conflict' ' + git merge --abort +' + +test_expect_success 'is aborted properly' ' + git status --porcelain -- modify_delete >out && + test_cmp empty out && + test_path_is_missing modify_delete +' + +test_done diff --git a/unpack-trees.c b/unpack-trees.c index 3a85a02..eb544ee 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1246,7 +1246,7 @@ static void mark_new_skip_worktree(struct exclude_list *el, if (select_flag && !(ce->ce_flags & select_flag)) continue; - if (!ce_stage(ce)) + if (!ce_stage(ce) && !(ce->ce_flags & CE_CONFLICTED)) ce->ce_flags |= skip_wt_flag; else ce->ce_flags &= ~skip_wt_flag; |