Skip to content

Commit df49b5f

Browse files
committed
merge-ort: expand only for out-of-cone conflicts
Merge conflicts happen often enough to want to avoid expanding a sparse index when they happen, as long as those conflicts are within the sparse-checkout cone. If a conflict exists outside of the sparse-checkout cone, then we still need to expand before iterating over the index entries. This is critical to do in advance because of how the original_cache_nr is tracked to allow inserting and replacing cache entries. Iterate over the conflicted files and check if any paths are outside of the sparse-checkout cone. If so, then expand the full index. Add a test that demonstrates that we do not expand the index, even when we hit a conflict within the sparse-checkout cone. Signed-off-by: Derrick Stolee <[email protected]>
1 parent d91a647 commit df49b5f

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

merge-ort.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4060,11 +4060,18 @@ static int record_conflicted_index_entries(struct merge_options *opt)
40604060

40614061
/*
40624062
* We are in a conflicted state. These conflicts might be inside
4063-
* sparse-directory entries, so expand the index preemtively.
4064-
* Also, we set original_cache_nr below, but that might change if
4063+
* sparse-directory entries, so check if any entries are outside
4064+
* of the sparse-checkout cone preemptively.
4065+
*
4066+
* We set original_cache_nr below, but that might change if
40654067
* index_name_pos() calls ask for paths within sparse directories.
40664068
*/
4067-
ensure_full_index(index);
4069+
strmap_for_each_entry(&opt->priv->conflicted, &iter, e) {
4070+
if (!path_in_sparse_checkout(e->key, index)) {
4071+
ensure_full_index(index);
4072+
break;
4073+
}
4074+
}
40684075

40694076
/* If any entries have skip_worktree set, we'll have to check 'em out */
40704077
state.force = 1;

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -617,8 +617,17 @@ test_expect_success 'sparse-index is expanded and converted back' '
617617
ensure_not_expanded () {
618618
rm -f trace2.txt &&
619619
echo >>sparse-index/untracked.txt &&
620-
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
621-
git -C sparse-index "$@" &&
620+
621+
if test "$1" = "!"
622+
then
623+
shift &&
624+
test_must_fail env \
625+
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
626+
git -C sparse-index "$@" || return 1
627+
else
628+
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
629+
git -C sparse-index "$@" || return 1
630+
fi &&
622631
test_region ! index ensure_full_index trace2.txt
623632
}
624633

@@ -658,6 +667,23 @@ test_expect_success 'sparse-index is not expanded' '
658667
)
659668
'
660669

670+
test_expect_success 'sparse-index is not expanded: merge conflict in cone' '
671+
init_repos &&
672+
673+
for side in right left
674+
do
675+
git -C sparse-index checkout -b expand-$side base &&
676+
echo $side >sparse-index/deep/a &&
677+
git -C sparse-index commit -a -m "$side" || return 1
678+
done &&
679+
680+
(
681+
sane_unset GIT_TEST_MERGE_ALGORITHM &&
682+
git -C sparse-index config pull.twohead ort &&
683+
ensure_not_expanded ! merge -m merged expand-right
684+
)
685+
'
686+
661687
# NEEDSWORK: a sparse-checkout behaves differently from a full checkout
662688
# in this scenario, but it shouldn't.
663689
test_expect_success 'reset mixed and checkout orphan' '

0 commit comments

Comments
 (0)