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

[PATCH 1/4] t6120: demonstrate weakness in disjoint-root handling

From
Jeff King <peff@peff.net>
Date
Nov 6, 2024, 21:16 UTC
Message-ID
<20241106211658.GA956383@coredump.intra.peff.net>
In-Reply-To
<20241106192236.GC880133@coredump.intra.peff.net>

Commit 30b1c7ad9d (describe: don't abort too early when searching tags, 2020-02-26) tried to fix a problem that happens when there are disjoint histories: to accurately compare the counts for different tags, we need to keep walking the history longer in order to find a common base.

But its fix misses a case: we may still bail early if we hit the max_candidates limit, producing suboptimal output. You can see this in action by adding "--candidates=2" to the tests; we'll stop traversing as soon as we see the second tag and will produce the wrong answer. I hit this in practice while trying to teach git-describe not to keep looking for candidates after we've seen all tags in the repo (effectively adding --candidates=2, since these toy repos have only two tags each).

This is probably fixable by continuing to walk after hitting the max-candidates limit, all the way down to a common ancestor of all candidates. But it's not clear in practice what the preformance implications would be (it would depend on how long the branches that hold the candidates are).

So I'm punting on that for now, but I'd like to adjust the tests to be more resilient, and to document the findings. So this patch:

  1. Adds an extra tag at the bottom of history. This shouldn't change
     the output, but does mean we are more resilient to low values of
     --candidates (e.g., if we start reducing it to the total number of
     tags). This is arguably closer to the real world anyway, where
     you're not going to have just 2 tags, but an arbitrarily long
     history going back in time, possibly with multiple irrelevant tags
     in it (I called the new tag "H" here for "history").
  2. Run the same tests with --candidates=2, which shows that even with
     the current code they can fail if we end the traversal early. That
     leaves a trail for anybody interested in trying to improve the
     behavior.
Signed-off-by: Jeff King <peff@peff.net>
---
 t/t6120-describe.sh | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index 05ed2510d9..69689d2f36 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -19,13 +19,17 @@ TEST_PASSES_SANITIZE_LEAK=true
 
 check_describe () {
 	indir= &&
+	outcome=success &&
 	while test $# != 0
 	do
 		case "$1" in
 		-C)
 			indir="$2"
 			shift
 			;;
+		--expect-failure)
+			outcome=failure
+			;;
 		*)
 			break
 			;;
@@ -36,7 +40,7 @@ check_describe () {
 	expect="$1"
 	shift
 	describe_opts="$@"
-	test_expect_success "describe $describe_opts" '
+	test_expect_${outcome} "describe $describe_opts" '
 		git ${indir:+ -C "$indir"} describe $describe_opts >raw &&
 		sed -e "s/-g[0-9a-f]*\$/-gHASH/" <raw >actual &&
 		echo "$expect" >expect &&
@@ -617,7 +621,7 @@ test_expect_success 'name-rev --annotate-stdin works with commitGraph' '
 
 #               B
 #               o
-#                \
+#  H             \
 #  o-----o---o----x
 #        A
 #
@@ -627,6 +631,7 @@ test_expect_success 'setup: describe commits with disjoint bases' '
 		cd disjoint1 &&
 
 		echo o >> file && git add file && git commit -m o &&
+		git tag H -a -m H &&
 		echo A >> file && git add file && git commit -m A &&
 		git tag A -a -m A &&
 		echo o >> file && git add file && git commit -m o &&
@@ -639,8 +644,9 @@ test_expect_success 'setup: describe commits with disjoint bases' '
 '
 
 check_describe -C disjoint1 "A-3-gHASH" HEAD
+check_describe -C disjoint1 --expect-failure "A-3-gHASH" --candidates=2 HEAD
 
-#           B
+#       H   B
 #   o---o---o------------.
 #                         \
 #                  o---o---x
@@ -658,13 +664,15 @@ test_expect_success 'setup: describe commits with disjoint bases 2' '
 		git checkout --orphan branch &&
 		echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:00" git commit -m o &&
 		echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:01" git commit -m o &&
+		git tag H -a -m H &&
 		echo B >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:02" git commit -m B &&
 		git tag B -a -m B &&
 		git merge --no-ff --allow-unrelated-histories main -m x
 	)
 '
 
 check_describe -C disjoint2 "B-3-gHASH" HEAD
+check_describe -C disjoint2 --expect-failure "B-3-gHASH" --candidates=2 HEAD
 
 test_expect_success 'setup misleading taggerdates' '
 	GIT_COMMITTER_DATE="2006-12-12 12:31" git tag -a -m "another tag" newer-tag-older-commit unique-file~1
-- 
2.47.0.441.g1a09955689
Previous: Jeff KingNext: Jeff King
Message 8 of 27 in “Re: [PATCH] setlocalversion: Add workaround for "git describe" performance issue”
  1. Rasmus VillemoesOct 31, 2024
  2. Jeff KingOct 31, 2024
  3. Jeff KingOct 31, 2024
  4. Jeff KingOct 31, 2024
  5. Benno EversNov 4, 2024
  6. 0/4 perf improvements for git-describe with few tagsJeff King, Nov 6, 2024
  7. Jeff KingNov 6, 2024
  8. 1/4 t6120: demonstrate weakness in disjoint-root handlingJeff King, Nov 6, 2024
  9. 2/4 t/perf: add tests for git-describeJeff King, Nov 6, 2024
  10. 3/4 describe: stop digging for max_candidates+1Jeff King, Nov 6, 2024
  11. 4/4 describe: stop traversing when we run out of namesJeff King, Nov 6, 2024
  12. fixup! describe: stop traversing when we run out of namesJosh Steadmon, Dec 4, 2024
  13. Jeff KingDec 4, 2024
  14. Jeff KingDec 4, 2024
  15. describe: drop early return for max_candidates == 0Jeff King, Dec 5, 2024
  16. Josh SteadmonDec 5, 2024
  17. Jeff KingDec 5, 2024
  18. Junio C HamanoDec 6, 2024
  19. Jeff KingDec 6, 2024
  20. Junio C HamanoDec 6, 2024
  21. describe: split "found all tags" and max_candidates logicJeff King, Dec 6, 2024
  22. Junio C HamanoNov 26, 2024
  23. Josh SteadmonDec 4, 2024
  24. Jeff KingDec 4, 2024
  25. Rasmus VillemoesNov 1, 2024
  26. Jeff KingNov 1, 2024
  27. Masahiro YamadaOct 31, 2024

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.