git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, newren@gmail.com,
	Phillip Wood <phillip.wood123@gmail.com>,
	Derrick Stolee <stolee@gmail.com>,
	Derrick Stolee <stolee@gmail.com>
Subject: [PATCH v2 1/4] apply: integrate with the sparse index
Date: Fri, 16 May 2025 14:55:27 +0000	[thread overview]
Message-ID: <1adf81ecb2c45c2e90d9b5dcfb02c814ecce6d8d.1747407330.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1914.v2.git.1747407330.gitgitgadget@gmail.com>

From: Derrick Stolee <stolee@gmail.com>

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 <stolee@gmail.com>
---
 builtin/apply.c                          |  7 +++-
 t/t1092-sparse-checkout-compatibility.sh | 53 ++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/builtin/apply.c b/builtin/apply.c
index 84f1863d3ac3..a1e20c593d09 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -12,7 +12,7 @@ static const char * const apply_usage[] = {
 int cmd_apply(int argc,
 	      const char **argv,
 	      const char *prefix,
-	      struct repository *repo UNUSED)
+	      struct repository *repo)
 {
 	int force_apply = 0;
 	int options = 0;
@@ -35,6 +35,11 @@ int cmd_apply(int argc,
 				   &state, &force_apply, &options,
 				   apply_usage);
 
+	if (repo) {
+		prepare_repo_settings(repo);
+		repo->settings.command_requires_full_index = 0;
+	}
+
 	if (check_apply_state(&state, force_apply))
 		exit(128);
 
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index f9b448792cb4..83353a7dbab4 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -1340,6 +1340,30 @@ test_expect_success 'submodule handling' '
 	grep "160000 $(git -C initial-repo rev-parse HEAD) 0	modules/sub" cache
 '
 
+test_expect_success 'git apply functionality' '
+	init_repos &&
+
+	test_all_match git checkout base &&
+
+	git -C full-checkout diff base..merge-right -- deep >patch-in-sparse &&
+	git -C full-checkout diff base..merge-right -- folder2 >patch-outside &&
+
+	# Apply a patch to a file inside the sparse definition
+	test_all_match git apply --index --stat ../patch-in-sparse &&
+	test_all_match git status --porcelain=v2 &&
+
+	# Apply a patch to a file outside the sparse definition
+	test_sparse_match test_must_fail git apply ../patch-outside &&
+	grep "No such file or directory" sparse-checkout-err &&
+
+	# But it works with --index and --cached
+	test_all_match git apply --index --stat ../patch-outside &&
+	test_all_match git status --porcelain=v2 &&
+	test_all_match git reset --hard &&
+	test_all_match git apply --cached --stat ../patch-outside &&
+	test_all_match git status --porcelain=v2
+'
+
 # When working with a sparse index, some commands will need to expand the
 # index to operate properly. If those commands also write the index back
 # to disk, they need to convert the index to sparse before writing.
@@ -2345,6 +2369,35 @@ test_expect_success 'sparse-index is not expanded: check-attr' '
 	ensure_not_expanded check-attr -a --cached -- folder1/a
 '
 
+test_expect_success 'sparse-index is not expanded: git apply' '
+	init_repos &&
+
+	git -C sparse-index checkout base &&
+	git -C full-checkout diff base..merge-right -- deep >patch-in-sparse &&
+	git -C full-checkout diff base..merge-right -- folder2 >patch-outside &&
+
+	# Apply a patch to a file inside the sparse definition
+	ensure_not_expanded apply --index --stat ../patch-in-sparse &&
+
+	# Apply a patch to a file outside the sparse definition
+	# Fails when caring about the worktree.
+	ensure_not_expanded ! apply ../patch-outside &&
+
+	# Expands when using --index.
+	ensure_expanded apply --index ../patch-outside &&
+
+	# Does not when index is partially expanded.
+	git -C sparse-index reset --hard &&
+	ensure_not_expanded apply --cached ../patch-outside &&
+
+	# Try again with a reset and collapsed index.
+	git -C sparse-index reset --hard &&
+	git -C sparse-index sparse-checkout reapply &&
+
+	# Expands when index is collapsed.
+	ensure_expanded apply --cached ../patch-outside
+'
+
 test_expect_success 'advice.sparseIndexExpanded' '
 	init_repos &&
 
-- 
gitgitgadget


  reply	other threads:[~2025-05-16 14:55 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-07  0:55 [PATCH 0/3] Integrate the sparse index with 'git apply' and 'git add -p/-i' Derrick Stolee via GitGitGadget
2025-05-07  0:55 ` [PATCH 1/3] apply: integrate with the sparse index Derrick Stolee via GitGitGadget
2025-05-10  3:18   ` Elijah Newren
2025-05-16 12:49     ` Derrick Stolee
2025-05-07  0:55 ` [PATCH 2/3] git add: make -p/-i aware of " Derrick Stolee via GitGitGadget
2025-05-10  4:38   ` Elijah Newren
2025-05-16 12:54     ` Derrick Stolee
2025-05-07  0:55 ` [PATCH 3/3] p2000: add performance test for 'git add -p' Derrick Stolee via GitGitGadget
2025-05-10  4:39   ` Elijah Newren
2025-05-08 18:26 ` [PATCH 0/3] Integrate the sparse index with 'git apply' and 'git add -p/-i' Junio C Hamano
2025-05-14 15:16 ` Phillip Wood
2025-05-16 13:28   ` Derrick Stolee
2025-05-20 15:07     ` phillip.wood123
2025-05-16 14:55 ` [PATCH v2 0/4] Integrate the sparse index with 'git apply' and interactive add, checkout, and reset Derrick Stolee via GitGitGadget
2025-05-16 14:55   ` Derrick Stolee via GitGitGadget [this message]
2025-05-16 14:55   ` [PATCH v2 2/4] git add: make -p/-i aware of sparse index Derrick Stolee via GitGitGadget
2025-05-16 14:55   ` [PATCH v2 3/4] reset: integrate sparse index with --patch Derrick Stolee via GitGitGadget
2025-05-16 16:20     ` Elijah Newren
2025-05-16 14:55   ` [PATCH v2 4/4] p2000: add performance test for patch-mode commands Derrick Stolee via GitGitGadget
2025-05-16 15:32   ` [PATCH v2 0/4] Integrate the sparse index with 'git apply' and interactive add, checkout, and reset Elijah Newren
2025-05-16 16:35     ` Derrick Stolee
2025-05-16 18:55     ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1adf81ecb2c45c2e90d9b5dcfb02c814ecce6d8d.1747407330.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=newren@gmail.com \
    --cc=phillip.wood123@gmail.com \
    --cc=stolee@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).