git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2] worktree: integrate with sparse-index

From
Shuqi Liang <cheskaqiqi@gmail.com>
Date
Jun 6, 2023, 17:26 UTC
Message-ID
<20230606172633.669916-1-cheskaqiqi@gmail.com>
In-Reply-To
<20230605161644.491424-1-cheskaqiqi@gmail.com>
The index is read in 'worktree.c' at two points:

1.The 'validate_no_submodules' function, which checks if there are any submodules present in the worktree.

2.The 'check_clean_worktree' function, which verifies if a worktree is 'clean', i.e., there are no untracked or modified but uncommitted files. This is done by running the 'git status' command, and an error message is thrown if the worktree is not clean. Given that 'git status' is already sparse-aware, the function is also sparse-aware.

Hence we can just set the requires-full-index to false for "git worktree".

Add tests that verify that 'git worktree' behaves correctly when the sparse index is enabled and test to ensure the index is not expanded.

The `p2000` tests demonstrate a ~20% execution time reduction for 'git worktree' using a sparse index:

(Note:the p2000 test results didn't reflect the huge speedup because of the index reading time is minuscule comparing to the filesystem operations.)

Test before after ----------------------------------------------------------------------- 2000.102: git worktree add....(full-v3) 3.15 2.82 -10.5% 2000.103: git worktree add....(full-v4) 3.14 2.84 -9.6% 2000.104: git worktree add....(sparse-v3) 2.59 2.14 -16.4% 2000.105: git worktree add....(sparse-v4) 2.10 1.57 -25.2%

Helped-by: Victoria Dye <vdye@github.com>
Signed-off-by: Shuqi Liang <cheskaqiqi@gmail.com>
---
Range-diff against v1:
* Fix did't to didn't.
* Add ensure_not_expanded for "git worktree add".
* Add a section that compares each test repo's default worktree to
a new worktree.
Range-diff against v1:
1:  aa772f998b ! 1:  d082c85fec worktree: integrate with sparse-index
    @@ Commit message
         The `p2000` tests demonstrate a ~20% execution time reduction for
         'git worktree' using a sparse index:
     
    -    (Note:the p2000 test results did't reflect the huge speedup because of
    +    (Note:the p2000 test results didn't reflect the huge speedup because of
         the index reading time is minuscule comparing to the filesystem
         operations.)
     
    @@ t/t1092-sparse-checkout-compatibility.sh: test_expect_success 'sparse index is n
     +	echo text >>"$1"
     +	EOF
     +
    -+	test_all_match git worktree add .worktrees/hotfix &&
    -+	test_sparse_match ls .worktrees/hotfix &&
    -+	test_all_match git worktree remove .worktrees/hotfix &&
    ++	for repo in full-checkout sparse-checkout sparse-index
    ++	do
    ++		worktree=${repo}-wt &&
    ++		git -C $repo worktree add ../$worktree &&
    ++
    ++		# Compare worktree content with "ls"
    ++		(cd $repo && ls) >worktree_contents &&
    ++		(cd $worktree && ls) >new_worktree_contents &&
    ++		test_cmp worktree_contents new_worktree_contents &&
    ++
    ++		# Compare index content with "ls-files --sparse"
    ++		git -C $repo ls-files --sparse >index_contents &&
    ++		git -C $worktree ls-files --sparse >new_index_contents &&
    ++		test_cmp index_contents new_index_contents &&
    ++
    ++		git -C $repo worktree remove ../$worktree || return 1
    ++	done &&
     +
     +	test_all_match git worktree add .worktrees/hotfix &&
     +	run_on_all ../edit-contents .worktrees/hotfix/deep/a &&
    @@ t/t1092-sparse-checkout-compatibility.sh: test_expect_success 'sparse index is n
     +test_expect_success 'worktree is not expanded' '
     +	init_repos &&
     +
    -+	test_all_match git worktree add .worktrees/hotfix &&
    ++	ensure_not_expanded worktree add .worktrees/hotfix &&
     +	ensure_not_expanded worktree remove .worktrees/hotfix
     +'
     +
-- 
2.39.0


 builtin/worktree.c                       |  4 +++
 t/perf/p2000-sparse-operations.sh        |  1 +
 t/t1092-sparse-checkout-compatibility.sh | 37 ++++++++++++++++++++++++
 3 files changed, 42 insertions(+)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index f3180463be..db14bff1a3 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -1200,5 +1200,9 @@ int cmd_worktree(int ac, const char **av, const char *prefix)
 		prefix = "";
 
 	ac = parse_options(ac, av, prefix, options, git_worktree_usage, 0);
+
+	prepare_repo_settings(the_repository);
+	the_repository->settings.command_requires_full_index = 0;
+
 	return fn(ac, av, prefix);
 }
diff --git a/t/perf/p2000-sparse-operations.sh b/t/perf/p2000-sparse-operations.sh
index 901cc493ef..1422136c73 100755
--- a/t/perf/p2000-sparse-operations.sh
+++ b/t/perf/p2000-sparse-operations.sh
@@ -131,5 +131,6 @@ test_perf_on_all git describe --dirty
 test_perf_on_all 'echo >>new && git describe --dirty'
 test_perf_on_all git diff-files
 test_perf_on_all git diff-files -- $SPARSE_CONE/a
+test_perf_on_all "git worktree add ../temp && git worktree remove ../temp"
 
 test_done
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index a63d0cc222..746203d375 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -2180,4 +2180,41 @@ test_expect_success 'sparse index is not expanded: diff-files' '
 	ensure_not_expanded diff-files -- "deep/*"
 '
 
+test_expect_success 'worktree' '
+	init_repos &&
+
+	write_script edit-contents <<-\EOF &&
+	echo text >>"$1"
+	EOF
+
+	for repo in full-checkout sparse-checkout sparse-index
+	do
+		worktree=${repo}-wt &&
+		git -C $repo worktree add ../$worktree &&
+
+		# Compare worktree content with "ls"
+		(cd $repo && ls) >worktree_contents &&
+		(cd $worktree && ls) >new_worktree_contents &&
+		test_cmp worktree_contents new_worktree_contents &&
+
+		# Compare index content with "ls-files --sparse"
+		git -C $repo ls-files --sparse >index_contents &&
+		git -C $worktree ls-files --sparse >new_index_contents &&
+		test_cmp index_contents new_index_contents &&
+
+		git -C $repo worktree remove ../$worktree || return 1
+	done &&
+
+	test_all_match git worktree add .worktrees/hotfix &&
+	run_on_all ../edit-contents .worktrees/hotfix/deep/a &&
+	test_all_match test_must_fail git worktree remove .worktrees/hotfix
+'
+
+test_expect_success 'worktree is not expanded' '
+	init_repos &&
+
+	ensure_not_expanded worktree add .worktrees/hotfix &&
+	ensure_not_expanded worktree remove .worktrees/hotfix
+'
+
 test_done
-- 
2.39.0
Previous: Victoria DyeNext: Victoria Dye
Message 5 of 6 in “worktree: integrate with sparse-index”
  1. worktree: integrate with sparse-indexShuqi Liang, Jun 5, 2023
  2. Victoria DyeJun 5, 2023
  3. Shuqi LiangJun 5, 2023
  4. Victoria DyeJun 6, 2023
  5. worktree: integrate with sparse-indexShuqi Liang, Jun 6, 2023
  6. Victoria DyeJun 7, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.