@@ -384,6 +384,44 @@ test_expect_success 'add, commit, checkout' '
384384 test_all_match git checkout -
385385'
386386
387+ test_expect_success ' git add, checkout, and reset with -p' '
388+ init_repos &&
389+
390+ write_script edit-contents <<-\EOF &&
391+ echo text >>$1
392+ EOF
393+
394+ # Does not expand when edits are within sparse checkout.
395+ run_on_all ../edit-contents deep/a &&
396+ run_on_all ../edit-contents deep/deeper1/a &&
397+
398+ test_write_lines y n >in &&
399+ run_on_all git add -p <in &&
400+ test_all_match git status --porcelain=v2 &&
401+ test_all_match git reset -p <in &&
402+
403+ test_write_lines u 1 "" q >in &&
404+ run_on_all git add -i <in &&
405+ test_all_match git status --porcelain=v2 &&
406+ test_all_match git reset --hard &&
407+
408+ run_on_sparse mkdir -p folder1 &&
409+ run_on_all ../edit-contents folder1/a &&
410+ test_write_lines y n y >in &&
411+ run_on_all git add -p <in &&
412+ test_sparse_match git status --porcelain=v2 &&
413+ test_sparse_match git reset &&
414+ test_write_lines u 2 3 "" q >in &&
415+ run_on_all git add -i <in &&
416+ test_sparse_match git status --porcelain=v2 &&
417+
418+ run_on_all git add --sparse folder1 &&
419+ run_on_all git commit -m "take changes" &&
420+ test_write_lines y n y >in &&
421+ test_sparse_match git checkout HEAD~1 --patch <in &&
422+ test_sparse_match git status --porcelain=v2
423+ '
424+
387425test_expect_success ' deep changes during checkout' '
388426 init_repos &&
389427
@@ -1340,6 +1378,30 @@ test_expect_success 'submodule handling' '
13401378 grep "160000 $(git -C initial-repo rev-parse HEAD) 0 modules/sub" cache
13411379'
13421380
1381+ test_expect_success ' git apply functionality' '
1382+ init_repos &&
1383+
1384+ test_all_match git checkout base &&
1385+
1386+ git -C full-checkout diff base..merge-right -- deep >patch-in-sparse &&
1387+ git -C full-checkout diff base..merge-right -- folder2 >patch-outside &&
1388+
1389+ # Apply a patch to a file inside the sparse definition
1390+ test_all_match git apply --index --stat ../patch-in-sparse &&
1391+ test_all_match git status --porcelain=v2 &&
1392+
1393+ # Apply a patch to a file outside the sparse definition
1394+ test_sparse_match test_must_fail git apply ../patch-outside &&
1395+ grep "No such file or directory" sparse-checkout-err &&
1396+
1397+ # But it works with --index and --cached
1398+ test_all_match git apply --index --stat ../patch-outside &&
1399+ test_all_match git status --porcelain=v2 &&
1400+ test_all_match git reset --hard &&
1401+ test_all_match git apply --cached --stat ../patch-outside &&
1402+ test_all_match git status --porcelain=v2
1403+ '
1404+
13431405# When working with a sparse index, some commands will need to expand the
13441406# index to operate properly. If those commands also write the index back
13451407# to disk, they need to convert the index to sparse before writing.
@@ -2345,6 +2407,95 @@ test_expect_success 'sparse-index is not expanded: check-attr' '
23452407 ensure_not_expanded check-attr -a --cached -- folder1/a
23462408'
23472409
2410+ test_expect_success ' sparse-index is not expanded: git apply' '
2411+ init_repos &&
2412+
2413+ git -C sparse-index checkout base &&
2414+ git -C full-checkout diff base..merge-right -- deep >patch-in-sparse &&
2415+ git -C full-checkout diff base..merge-right -- folder2 >patch-outside &&
2416+
2417+ # Apply a patch to a file inside the sparse definition
2418+ ensure_not_expanded apply --index --stat ../patch-in-sparse &&
2419+
2420+ # Apply a patch to a file outside the sparse definition
2421+ # Fails when caring about the worktree.
2422+ ensure_not_expanded ! apply ../patch-outside &&
2423+
2424+ # Expands when using --index.
2425+ ensure_expanded apply --index ../patch-outside &&
2426+
2427+ # Does not when index is partially expanded.
2428+ git -C sparse-index reset --hard &&
2429+ ensure_not_expanded apply --cached ../patch-outside &&
2430+
2431+ # Try again with a reset and collapsed index.
2432+ git -C sparse-index reset --hard &&
2433+ git -C sparse-index sparse-checkout reapply &&
2434+
2435+ # Expands when index is collapsed.
2436+ ensure_expanded apply --cached ../patch-outside
2437+ '
2438+
2439+ test_expect_success ' sparse-index is not expanded: git add -p' '
2440+ init_repos &&
2441+
2442+ # Does not expand when edits are within sparse checkout.
2443+ echo "new content" >sparse-index/deep/a &&
2444+ echo "new content" >sparse-index/deep/deeper1/a &&
2445+ test_write_lines y n >in &&
2446+ ensure_not_expanded add -p <in &&
2447+ git -C sparse-index reset &&
2448+ ensure_not_expanded add -i <in &&
2449+
2450+ # -p does expand when edits are outside sparse checkout.
2451+ mkdir -p sparse-index/folder1 &&
2452+ echo "new content" >sparse-index/folder1/a &&
2453+ test_write_lines y n y >in &&
2454+ ensure_expanded add -p <in &&
2455+
2456+ # Fully reset the index.
2457+ git -C sparse-index reset --hard &&
2458+ git -C sparse-index sparse-checkout reapply &&
2459+
2460+ # -i does expand when edits are outside sparse checkout.
2461+ mkdir -p sparse-index/folder1 &&
2462+ echo "new content" >sparse-index/folder1/a &&
2463+ test_write_lines u 2 3 "" q >in &&
2464+ ensure_expanded add -i <in
2465+ '
2466+
2467+ test_expect_success ' sparse-index is not expanded: checkout -p, reset -p' '
2468+ init_repos &&
2469+
2470+ # Does not expand when edits are within sparse checkout.
2471+ echo "new content" >sparse-index/deep/a &&
2472+ echo "new content" >sparse-index/deep/deeper1/a &&
2473+ git -C sparse-index commit -a -m "inside-changes" &&
2474+
2475+ test_write_lines y y >in &&
2476+ ensure_not_expanded checkout HEAD~1 --patch <in &&
2477+
2478+ echo "new content" >sparse-index/deep/a &&
2479+ echo "new content" >sparse-index/deep/deeper1/a &&
2480+ git -C sparse-index add . &&
2481+ ensure_not_expanded reset --patch <in &&
2482+
2483+ # -p does expand when edits are outside sparse checkout.
2484+ mkdir -p sparse-index/folder1 &&
2485+ echo "new content" >sparse-index/folder1/a &&
2486+ git -C sparse-index add --sparse folder1 &&
2487+ git -C sparse-index sparse-checkout reapply &&
2488+ ensure_expanded reset --patch <in &&
2489+
2490+ # Fully reset the index.
2491+ mkdir -p sparse-index/folder1 &&
2492+ echo "new content" >sparse-index/folder1/a &&
2493+ git -C sparse-index add --sparse folder1 &&
2494+ git -C sparse-index commit -m "folder1 change" &&
2495+ git -C sparse-index sparse-checkout reapply &&
2496+ ensure_expanded checkout HEAD~1 --patch <in
2497+ '
2498+
23482499test_expect_success ' advice.sparseIndexExpanded' '
23492500 init_repos &&
23502501
0 commit comments