Skip to content

Commit d91a647

Browse files
committed
merge: make sparse-aware with ORT
Allow 'git merge' to operate without expanding a sparse index, at least not immediately. The index still will be expanded in a few cases: 1. If the merge strategy is 'recursive', then we enable command_requires_full_index at the start of the merge_recursive() method. We expect sparse-index users to also have the 'ort' strategy enabled. 2. If the merge results in a conflicted file, then we expand the index before updating the working tree. The loop that iterates over the worktree replaces index entries and tracks 'origintal_cache_nr' which can become completely wrong if the index expands in the middle of the operation. This safety valve is important before that loop starts. A later change will focus this to only expand if we indeed have a conflict outside of the sparse-checkout cone. Some test updates are required, including a mistaken 'git checkout -b' that did not specify the base branch, causing merges to be fast-forward merges. Signed-off-by: Derrick Stolee <[email protected]>
1 parent 080b02c commit d91a647

File tree

4 files changed

+24
-2
lines changed

4 files changed

+24
-2
lines changed

builtin/merge.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,6 +1276,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
12761276
if (argc == 2 && !strcmp(argv[1], "-h"))
12771277
usage_with_options(builtin_merge_usage, builtin_merge_options);
12781278

1279+
prepare_repo_settings(the_repository);
1280+
the_repository->settings.command_requires_full_index = 0;
1281+
12791282
/*
12801283
* Check if we are _not_ on a detached HEAD, i.e. if there is a
12811284
* current branch.

merge-ort.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4058,6 +4058,14 @@ static int record_conflicted_index_entries(struct merge_options *opt)
40584058
if (strmap_empty(&opt->priv->conflicted))
40594059
return 0;
40604060

4061+
/*
4062+
* 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
4065+
* index_name_pos() calls ask for paths within sparse directories.
4066+
*/
4067+
ensure_full_index(index);
4068+
40614069
/* If any entries have skip_worktree set, we'll have to check 'em out */
40624070
state.force = 1;
40634071
state.quiet = 1;

merge-recursive.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3750,6 +3750,9 @@ int merge_recursive(struct merge_options *opt,
37503750
assert(opt->ancestor == NULL ||
37513751
!strcmp(opt->ancestor, "constructed merge base"));
37523752

3753+
prepare_repo_settings(opt->repo);
3754+
opt->repo->settings.command_requires_full_index = 1;
3755+
37533756
if (merge_start(opt, repo_get_commit_tree(opt->repo, h1)))
37543757
return -1;
37553758
clean = merge_recursive_internal(opt, h1, h2, merge_bases, result);

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ test_expect_success 'setup' '
4747
git checkout -b base &&
4848
for dir in folder1 folder2 deep
4949
do
50-
git checkout -b update-$dir &&
50+
git checkout -b update-$dir base &&
5151
echo "updated $dir" >$dir/a &&
5252
git commit -a -m "update $dir" || return 1
5353
done &&
@@ -647,7 +647,15 @@ test_expect_success 'sparse-index is not expanded' '
647647
echo >>sparse-index/extra.txt &&
648648
ensure_not_expanded add extra.txt &&
649649
echo >>sparse-index/untracked.txt &&
650-
ensure_not_expanded add .
650+
ensure_not_expanded add . &&
651+
652+
ensure_not_expanded checkout -f update-deep &&
653+
(
654+
sane_unset GIT_TEST_MERGE_ALGORITHM &&
655+
git -C sparse-index config pull.twohead ort &&
656+
ensure_not_expanded merge -m merge update-folder1 &&
657+
ensure_not_expanded merge -m merge update-folder2
658+
)
651659
'
652660

653661
# NEEDSWORK: a sparse-checkout behaves differently from a full checkout

0 commit comments

Comments
 (0)