Subject: [PATCH v3] describe: enable sparse index for describe

From: "Raghul Nanth A via GitGitGadget" <[email-masked]>
Date: Thu, 30 Mar 2023 05:59:16 +0000

From: Raghul Nanth A <[email-masked]>

Add usage and performance tests for describe

Describe uses the index when it is run with --dirty flag, which uses the
run_diff_index commmand. The command is sparse-index aware and hence we
can just set the requires-full-index to false

Performance metrics

  Test                                                     HEAD~1            HEAD
  -------------------------------------------------------------------------------------------------
  2000.2: git describe --dirty (full-v3)                   0.08(0.09+0.01)   0.08(0.06+0.03) +0.0%
  2000.3: git describe --dirty (full-v4)                   0.09(0.07+0.03)   0.08(0.05+0.04) -11.1%
  2000.4: git describe --dirty (sparse-v3)                 0.88(0.82+0.06)   0.02(0.01+0.05) -97.7%
  2000.5: git describe --dirty (sparse-v4)                 0.68(0.60+0.08)   0.02(0.02+0.04) -97.1%
  2000.6: echo >>new && git describe --dirty (full-v3)     0.08(0.04+0.05)   0.08(0.05+0.04) +0.0%
  2000.7: echo >>new && git describe --dirty (full-v4)     0.08(0.07+0.03)   0.08(0.05+0.04) +0.0%
  2000.8: echo >>new && git describe --dirty (sparse-v3)   0.75(0.69+0.07)   0.02(0.03+0.03) -97.3%
  2000.9: echo >>new && git describe --dirty (sparse-v4)   0.81(0.73+0.09)   0.02(0.01+0.05) -97.5%

Signed-off-by: Raghul Nanth A <[email-masked]>
---
    describe: enable sparse index for describe
    
     * Removed describe tests not concerned with sparse index
    
     * Added performance metric to commit message
    
     * Moved tests to t1092.sh
    
     * Explained reason for changes in commit message

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1480%2FNanthR%2Fdescribe-sparse-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1480/NanthR/describe-sparse-v3
Pull-Request: https://github.com/git/git/pull/1480

Range-diff vs v2:

 1:  03176f64607 ! 1:  01838ca3ab0 describe: enable sparse index for describe
     @@ Commit message
      
          Add usage and performance tests for describe
      
     +    Describe uses the index when it is run with --dirty flag, which uses the
     +    run_diff_index commmand. The command is sparse-index aware and hence we
     +    can just set the requires-full-index to false
     +
          Performance metrics
      
            Test                                                     HEAD~1            HEAD
     @@ t/t1092-sparse-checkout-compatibility.sh: test_expect_success 'sparse-index is n
      +test_expect_success 'sparse-index is not expanded: describe' '
      +	init_repos &&
      +	# Add tag to be read by describe
     -+	ensure_not_expanded tag -a v1.0 -m "Version 1" &&
     ++	git -C sparse-index tag -a v1.0 -m "Version 1" &&
      +	ensure_not_expanded describe --dirty &&
     ++	cp sparse-index-out sparse-index-dirty &&
      +	ensure_not_expanded describe &&
     -+	echo "test" >>sparse-index/extra.txt &&
     ++	cp sparse-index-out sparse-index-normal &&
     ++	# Check describe has same output on clean tree
     ++	test_cmp sparse-index-dirty sparse-index-normal &&
     ++	echo "test" >>sparse-index/g &&
      +	ensure_not_expanded describe --dirty &&
     ++	echo "v1.0-dirty" > actual &&
     ++	# Check describe on dirty work tree
     ++	test_cmp sparse-index-out actual &&
      +	ensure_not_expanded describe
      +'
      +
       test_expect_success 'sparse index is not expanded: diff' '
       	init_repos &&
       
     -
     - ## t/t6121-describe-sparse.sh (new) ##
     -@@
     -+#!/bin/sh
     -+
     -+test_description='git describe in sparse checked out trees'
     -+
     -+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
     -+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
     -+
     -+. ./test-lib.sh
     -+
     -+check_describe () {
     -+	indir= &&
     -+	while test $# != 0
     -+	do
     -+		case "$1" in
     -+		-C)
     -+			indir="$2"
     -+			shift
     -+			;;
     -+		*)
     -+			break
     -+			;;
     -+		esac
     -+		shift
     -+	done &&
     -+	indir=${indir:+"$indir"/} &&
     -+	expect="$1"
     -+	shift
     -+	describe_opts="$@"
     -+	test_expect_success "describe $describe_opts" '
     -+		git ${indir:+ -C "$indir"} describe $describe_opts >actual &&
     -+		echo "$expect" >expect &&
     -+		test_cmp expect actual
     -+	'
     -+}
     -+
     -+test_expect_success setup '
     -+	test_commit initial file one &&
     -+	test_commit --annotate A file A &&
     -+
     -+	test_tick &&
     -+
     -+	git sparse-checkout init --cone
     -+'
     -+
     -+check_describe A HEAD
     -+
     -+test_expect_success 'describe --dirty with --work-tree' '
     -+	(
     -+		cd "$TEST_DIRECTORY" &&
     -+		git --git-dir "$TRASH_DIRECTORY/.git" --work-tree "$TRASH_DIRECTORY" describe --dirty >"$TRASH_DIRECTORY/out"
     -+	) &&
     -+	grep "A" out
     -+'
     -+
     -+test_expect_success 'set-up dirty work tree' '
     -+	echo >>file
     -+'
     -+
     -+test_expect_success 'describe --dirty with --work-tree (dirty)' '
     -+	git describe --dirty >expected &&
     -+	(
     -+		cd "$TEST_DIRECTORY" &&
     -+		git --git-dir "$TRASH_DIRECTORY/.git" --work-tree "$TRASH_DIRECTORY" describe --dirty >"$TRASH_DIRECTORY/out"
     -+	) &&
     -+	test_cmp expected out
     -+'
     -+test_done

 builtin/describe.c                       |  2 ++
 t/perf/p2000-sparse-operations.sh        |  3 +++
 t/t1092-sparse-checkout-compatibility.sh | 18 ++++++++++++++++++
 3 files changed, 23 insertions(+)

diff --git a/builtin/describe.c b/builtin/describe.c
index 5b5930f5c8c..7ff9b5e4b20 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -654,6 +654,8 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
 			int fd, result;
 
 			setup_work_tree();
+			prepare_repo_settings(the_repository);
+			the_repository->settings.command_requires_full_index = 0;
 			repo_read_index(the_repository);
 			refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED,
 				      NULL, NULL, NULL);
diff --git a/t/perf/p2000-sparse-operations.sh b/t/perf/p2000-sparse-operations.sh
index 3242cfe91a0..db7887470f9 100755
--- a/t/perf/p2000-sparse-operations.sh
+++ b/t/perf/p2000-sparse-operations.sh
@@ -43,6 +43,7 @@ test_expect_success 'setup repo and indexes' '
 	done &&
 
 	git sparse-checkout init --cone &&
+	git tag -a v1.0 -m "Final" &&
 	git sparse-checkout set $SPARSE_CONE &&
 	git checkout -b wide $OLD_COMMIT &&
 
@@ -125,5 +126,7 @@ test_perf_on_all git checkout-index -f --all
 test_perf_on_all git update-index --add --remove $SPARSE_CONE/a
 test_perf_on_all "git rm -f $SPARSE_CONE/a && git checkout HEAD -- $SPARSE_CONE/a"
 test_perf_on_all git grep --cached --sparse bogus -- "f2/f1/f1/*"
+test_perf_on_all git describe --dirty
+test_perf_on_all 'echo >>new && git describe --dirty'
 
 test_done
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index 801919009e1..8bc35c51426 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -1514,6 +1514,24 @@ test_expect_success 'sparse-index is not expanded: stash' '
 	ensure_not_expanded stash pop
 '
 
+test_expect_success 'sparse-index is not expanded: describe' '
+	init_repos &&
+	# Add tag to be read by describe
+	git -C sparse-index tag -a v1.0 -m "Version 1" &&
+	ensure_not_expanded describe --dirty &&
+	cp sparse-index-out sparse-index-dirty &&
+	ensure_not_expanded describe &&
+	cp sparse-index-out sparse-index-normal &&
+	# Check describe has same output on clean tree
+	test_cmp sparse-index-dirty sparse-index-normal &&
+	echo "test" >>sparse-index/g &&
+	ensure_not_expanded describe --dirty &&
+	echo "v1.0-dirty" > actual &&
+	# Check describe on dirty work tree
+	test_cmp sparse-index-out actual &&
+	ensure_not_expanded describe
+'
+
 test_expect_success 'sparse index is not expanded: diff' '
 	init_repos &&

base-commit: 27d43aaaf50ef0ae014b88bba294f93658016a2e
-- 
gitgitgadget