It's a very unexpected behaviour when a user sees a deleted file after a merge with enabled sparse-checkout. Moreover, when the user resolves merge conflicts and commits the changes with the command "git commit -am xxx", a repository can be broken because all the moved files will be deleted. Finally, it's really hard to find a user who deleted these files because "git log file" doesn't show any merge commits by default. I'm not sure that my fix is correct but I checked all tests and I didn't find a better way to prevent files deleting. --- merge-recursive.c | 9 +++++--- t/t6042-merge-rename-corner-cases.sh | 41 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index e349126..25dc701 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1724,9 +1724,12 @@ static int merge_content(struct merge_options *o, */ path_renamed_outside_HEAD = !path2 || !strcmp(path, path2); if (!path_renamed_outside_HEAD) { - add_cacheinfo(o, mfi.mode, &mfi.oid, path, - 0, (!o->call_depth), 0); - return mfi.clean; + struct stat st; + if (lstat(path, &st) == 0) { + add_cacheinfo(o, mfi.mode, &mfi.oid, path, + 0, (!o->call_depth), 0); + return mfi.clean; + } } } else output(o, 2, _("Auto-merging %s"), path); diff --git a/t/t6042-merge-rename-corner-cases.sh b/t/t6042-merge-rename-corner-cases.sh index 411550d..5d84418 100755 --- a/t/t6042-merge-rename-corner-cases.sh +++ b/t/t6042-merge-rename-corner-cases.sh @@ -575,4 +575,45 @@ test_expect_success 'rename/rename/add-dest merge still knows about conflicting test ! -f c ' +test_expect_success 'move file/sparse-checkout/merge should not delete moved file' ' + git rm -rf . && + git clean -fdqx && + rm -rf .git && + git init && + + echo output >.gitignore && + echo .gitignore >>.gitignore && + + echo b1 >b1 && + git add b1 && + git commit -m b1 && + + mkdir excluded && + echo problem >excluded/to-be-moved.txt && + git add excluded/to-be-moved.txt && + git commit -m to-be-moved && + git tag split_point && + + echo b2 >b2 && + git add b2 && + git commit -m b2 && + git tag b2 && + + git reset --hard split_point && + + git mv excluded/to-be-moved.txt excluded/moved.txt && + git commit -m move && + git tag b1 && + + git config core.sparsecheckout true && + echo "/*" >.git/info/sparse-checkout && + echo "!excluded/" >>.git/info/sparse-checkout && + git read-tree -mu HEAD && + + git merge -m merge b2 && + + git status >output && + test_i18ngrep "nothing to commit" output +' + test_done -- 2.7.4 (Apple Git-66)