From: Derrick Stolee <dstolee@xxxxxxxxxxxxx> When 'git add' adds a tracked file that is outside of the sparse-checkout cone, it checks the SKIP_WORKTREE bit to see if the file exists outside of the sparse-checkout cone. This is usually correct, except in the case of a merge conflict outside of the cone. Modify add_pathspec_matched_against_index() to be more careful about pathes by checking the sparse-checkout patterns in addition to the SKIP_WORKTREE bit. This causes 'git add' to no longer allow files outside of the cone that removed the SKIP_WORKTREE bit due to a merge conflict. With only this change, users will only be able to add the file after adding the file to the sparse-checkout cone. A later change will allow users to force adding even though the file is outside of the sparse-checkout cone. Signed-off-by: Derrick Stolee <dstolee@xxxxxxxxxxxxx> --- pathspec.c | 3 ++- t/t1092-sparse-checkout-compatibility.sh | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pathspec.c b/pathspec.c index 44306fdaca2..0e6e60fdc5a 100644 --- a/pathspec.c +++ b/pathspec.c @@ -39,7 +39,8 @@ void add_pathspec_matches_against_index(const struct pathspec *pathspec, return; for (i = 0; i < istate->cache_nr; i++) { const struct cache_entry *ce = istate->cache[i]; - if (sw_action == PS_IGNORE_SKIP_WORKTREE && ce_skip_worktree(ce)) + if (sw_action == PS_IGNORE_SKIP_WORKTREE && + (ce_skip_worktree(ce) || !path_in_sparse_checkout(ce->name, istate))) continue; ce_path_match(istate, ce, pathspec, seen); } diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index 962bece03e1..c2a4eec548d 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -529,7 +529,7 @@ test_expect_failure 'merge with conflict outside cone' ' # NEEDSWORK: Even though the merge conflict removed the # SKIP_WORKTREE bit from the index entry for folder1/a, we should # warn that this is a problematic add. - test_all_match git add folder1/a && + test_sparse_match test_must_fail git add folder1/a && test_all_match git status --porcelain=v2 && # 3. Rename the file to another sparse filename and @@ -538,7 +538,7 @@ test_expect_failure 'merge with conflict outside cone' ' # NEEDSWORK: This mode now fails, because folder2/z is # outside of the sparse-checkout cone and does not match an # existing index entry with the SKIP_WORKTREE bit cleared. - test_all_match git add folder2 && + test_sparse_match test_must_fail git add folder2 && test_all_match git status --porcelain=v2 && test_all_match git merge --continue && @@ -566,7 +566,7 @@ test_expect_failure 'cherry-pick/rebase with conflict outside cone' ' # NEEDSWORK: Even though the merge conflict removed the # SKIP_WORKTREE bit from the index entry for folder1/a, we should # warn that this is a problematic add. - test_all_match git add folder1/a && + test_sparse_match test_must_fail git add folder1/a && test_all_match git status --porcelain=v2 && # 3. Rename the file to another sparse filename and @@ -575,7 +575,7 @@ test_expect_failure 'cherry-pick/rebase with conflict outside cone' ' # outside of the sparse-checkout cone and does not match an # existing index entry with the SKIP_WORKTREE bit cleared. run_on_all mv folder2/a folder2/z && - test_all_match git add folder2 && + test_sparse_match test_must_fail git add folder2 && test_all_match git status --porcelain=v2 && test_all_match git $OPERATION --continue && -- gitgitgadget