[PATCH v7 10/16] unpack-trees: handle dir/file conflict of sparse entries
From: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
---
t/t1092-sparse-checkout-compatibility.sh | 25 ++++++++++++++++++++++--
unpack-trees.c | 5 ++++-
2 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index 3f61e5686b5..4e6446e7545 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -95,6 +95,19 @@ test_expect_success 'setup' '
git add . &&
git commit -m "rename deep/deeper1/... to folder1/..." &&
+ git checkout -b df-conflict base &&
+ rm -rf folder1 &&
+ echo content >folder1 &&
+ git add . &&
+ git commit -m df &&
+
+ git checkout -b fd-conflict base &&
+ rm a &&
+ mkdir a &&
+ echo content >a/a &&
+ git add . &&
+ git commit -m fd &&
+
git checkout -b deepest base &&
echo "updated deepest" >deep/deeper1/deepest/a &&
git commit -a -m "update deepest" &&
@@ -325,7 +338,11 @@ test_expect_success 'diff --staged' '
test_expect_success 'diff with renames and conflicts' '
init_repos &&
- for branch in rename-out-to-out rename-out-to-in rename-in-to-out
+ for branch in rename-out-to-out \
+ rename-out-to-in \
+ rename-in-to-out \
+ df-conflict \
+ fd-conflict
do
test_all_match git checkout rename-base &&
test_all_match git checkout $branch -- .&&
@@ -338,7 +355,11 @@ test_expect_success 'diff with renames and conflicts' '
test_expect_success 'diff with directory/file conflicts' '
init_repos &&
- for branch in rename-out-to-out rename-out-to-in rename-in-to-out
+ for branch in rename-out-to-out \
+ rename-out-to-in \
+ rename-in-to-out \
+ df-conflict \
+ fd-conflict
do
git -C full-checkout reset --hard &&
test_sparse_match git reset --hard &&
diff --git a/unpack-trees.c b/unpack-trees.c
index d141dffbd94..e63b2dcacbc 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -2617,7 +2617,10 @@ int twoway_merge(const struct cache_entry * const *src,
same(current, oldtree) && !same(current, newtree)) {
/* 20 or 21 */
return merged_entry(newtree, current, o);
- } else
+ } else if (current && !oldtree && newtree &&
+ S_ISSPARSEDIR(current->ce_mode) != S_ISSPARSEDIR(newtree->ce_mode))
+ return merged_entry(newtree, current, o);
+ else
return reject_merge(current, o);
}
else if (newtree) {
--
gitgitgadget