Skip to content

Commit c5b1cba

Browse files
committed
apply: integrate with the sparse index
The sparse index allows storing directory entries in the index, marked with the skip-wortkree bit and pointing to a tree object. This may be an unexpected data shape for some implementation areas, so we are rolling it out incrementally on a builtin-per-builtin basis. This change enables the sparse index for 'git apply'. The main motivation for this change is that 'git apply' is used as a child process of 'git add -p' and expanding the sparse index for each of those child processes can lead to significant performance issues. The good news is that the actual index manipulation code used by 'git apply' is already integrated with the sparse index, so the only product change is to mark the builtin as allowing the sparse index so it isn't inflated on read. The more involved part of this change is around adding tests that verify how 'git apply' behaves in a sparse-checkout environment and whether or not the index expands in certain operations. Signed-off-by: Derrick Stolee <[email protected]>
1 parent 6c0bd1f commit c5b1cba

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

builtin/apply.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ static const char * const apply_usage[] = {
1212
int cmd_apply(int argc,
1313
const char **argv,
1414
const char *prefix,
15-
struct repository *repo UNUSED)
15+
struct repository *repo)
1616
{
1717
int force_apply = 0;
1818
int options = 0;
@@ -35,6 +35,9 @@ int cmd_apply(int argc,
3535
&state, &force_apply, &options,
3636
apply_usage);
3737

38+
prepare_repo_settings(repo);
39+
repo->settings.command_requires_full_index = 0;
40+
3841
if (check_apply_state(&state, force_apply))
3942
exit(128);
4043

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,30 @@ test_expect_success 'submodule handling' '
13401340
grep "160000 $(git -C initial-repo rev-parse HEAD) 0 modules/sub" cache
13411341
'
13421342

1343+
test_expect_success 'git apply functionality' '
1344+
init_repos &&
1345+
1346+
test_all_match git checkout base &&
1347+
1348+
git -C full-checkout diff base..merge-right -- deep >patch-in-sparse &&
1349+
git -C full-checkout diff base..merge-right -- folder2 >patch-outside &&
1350+
1351+
# Apply a patch to a file inside the sparse definition
1352+
test_all_match git apply --index --stat ../patch-in-sparse &&
1353+
test_all_match git status --porcelain=v2 &&
1354+
1355+
# Apply a patch to a file outside the sparse definition
1356+
test_sparse_match test_must_fail git apply ../patch-outside &&
1357+
grep "No such file or directory" sparse-checkout-err &&
1358+
1359+
# But it works with --index and --cached
1360+
test_all_match git apply --index --stat ../patch-outside &&
1361+
test_all_match git status --porcelain=v2 &&
1362+
test_all_match git reset --hard &&
1363+
test_all_match git apply --cached --stat ../patch-outside &&
1364+
test_all_match git status --porcelain=v2
1365+
'
1366+
13431367
# When working with a sparse index, some commands will need to expand the
13441368
# index to operate properly. If those commands also write the index back
13451369
# to disk, they need to convert the index to sparse before writing.
@@ -2345,6 +2369,28 @@ test_expect_success 'sparse-index is not expanded: check-attr' '
23452369
ensure_not_expanded check-attr -a --cached -- folder1/a
23462370
'
23472371

2372+
test_expect_success 'sparse-index is not expanded: git apply' '
2373+
init_repos &&
2374+
2375+
git -C sparse-index checkout base &&
2376+
git -C full-checkout diff base..merge-right -- deep >patch-in-sparse &&
2377+
git -C full-checkout diff base..merge-right -- folder2 >patch-outside &&
2378+
2379+
# Apply a patch to a file inside the sparse definition
2380+
ensure_not_expanded apply --index --stat ../patch-in-sparse &&
2381+
2382+
# Apply a patch to a file outside the sparse definition
2383+
# Fails when caring about the worktree.
2384+
ensure_not_expanded ! apply ../patch-outside &&
2385+
2386+
# Expands when using --index.
2387+
ensure_expanded apply --index ../patch-outside &&
2388+
git -C sparse-index reset --hard &&
2389+
2390+
# Does not expand when using --cached.
2391+
ensure_not_expanded apply --cached ../patch-outside
2392+
'
2393+
23482394
test_expect_success 'advice.sparseIndexExpanded' '
23492395
init_repos &&
23502396

0 commit comments

Comments
 (0)