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

[PATCH 11/16] refs: omit dangling symrefs when using GIT_REF_PARANOIA

From
Jeff King <peff@peff.net>
Date
Sep 24, 2021, 18:42 UTC
Message-ID
<YU4cHlGaEwBzTJ0k@coredump.intra.peff.net>
In-Reply-To
<YU4ZOF9+ubmoItmK@coredump.intra.peff.net>

Dangling symrefs aren't actually a corruption problem. It's perfectly fine for refs/remotes/origin/HEAD to point to an unborn branch. And in particular, if you are trying to establish reachability, a symref that points nowhere doesn't matter either way. Any ref it could point to will be examined during the rest of the traversal.

It's possible that a symref pointing nowhere _could_ be a sign that the ref it was meant to point to was deleted accidentally (e.g., via corruption). But there is no particular reason to think that is true for any given case, and in the meantime, GIT_REF_PARANOIA kicking in automatically for some operations means they'll fail unnecessarily.

So let's loosen it just a bit. The new test in t5312 shows off an example that is safe, but currently fails (and no longer does after this patch).

Note that we don't do anything if the caller explicitly asked for DO_FOR_EACH_INCLUDE_BROKEN. In that case they may be looking for dangling symrefs themselves, and setting GIT_REF_PARANOIA should not _loosen_ things from what the caller asked for.

Signed-off-by: Jeff King <peff@peff.net>
---
 refs.c                      | 12 ++++++++----
 t/t5312-prune-corruption.sh |  7 +++++++
 2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/refs.c b/refs.c
index c28bd6a818..e72510813e 100644
--- a/refs.c
+++ b/refs.c
@@ -1418,10 +1418,14 @@ struct ref_iterator *refs_ref_iterator_begin(
 {
 	struct ref_iterator *iter;
 
-	if (ref_paranoia < 0)
-		ref_paranoia = git_env_bool("GIT_REF_PARANOIA", 0);
-	if (ref_paranoia)
-		flags |= DO_FOR_EACH_INCLUDE_BROKEN;
+	if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
+		if (ref_paranoia < 0)
+			ref_paranoia = git_env_bool("GIT_REF_PARANOIA", 0);
+		if (ref_paranoia) {
+			flags |= DO_FOR_EACH_INCLUDE_BROKEN;
+			flags |= DO_FOR_EACH_OMIT_DANGLING_SYMREFS;
+		}
+	}
 
 	iter = refs->be->iterator_begin(refs, prefix, flags);
 
diff --git a/t/t5312-prune-corruption.sh b/t/t5312-prune-corruption.sh
index 1522a4ba8e..d8ec5a7462 100755
--- a/t/t5312-prune-corruption.sh
+++ b/t/t5312-prune-corruption.sh
@@ -62,6 +62,13 @@ test_expect_success 'destructive repack keeps packed object' '
 	git cat-file -e $bogus
 '
 
+test_expect_success 'destructive repack not confused by dangling symref' '
+	test_when_finished "git symbolic-ref -d refs/heads/dangling" &&
+	git symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&
+	git repack -ad &&
+	test_must_fail git cat-file -e $bogus
+'
+
 # We create two new objects here, "one" and "two". Our
 # main branch points to "two", which is deleted,
 # corrupting the repository. But we'd like to make sure
-- 
2.33.0.1071.gb37e412355
Previous: Jeff KingNext: Jeff King
Message 14 of 22 in “enabling GIT_REF_PARANOIA by default”
  1. 0/16 enabling GIT_REF_PARANOIA by defaultJeff King, Sep 24, 2021
  2. 01/16 t7900: clean up some more broken refsJeff King, Sep 24, 2021
  3. Jonathan TanSep 27, 2021
  4. Jeff KingSep 27, 2021
  5. 02/16 t5516: don't use HEAD ref for invalid ref-deletion testsJeff King, Sep 24, 2021
  6. 03/16 t5600: provide detached HEAD for corruption failuresJeff King, Sep 24, 2021
  7. 04/16 t5312: drop "verbose" helperJeff King, Sep 24, 2021
  8. 05/16 t5312: create bogus ref as necessaryJeff King, Sep 24, 2021
  9. 06/16 t5312: test non-destructive repackJeff King, Sep 24, 2021
  10. 07/16 t5312: be more assertive about command failureJeff King, Sep 24, 2021
  11. 08/16 refs-internal.h: move DO_FOR_EACH_* flags next to each otherJeff King, Sep 24, 2021
  12. 09/16 refs-internal.h: reorganize DO_FOR_EACH_* flag documentationJeff King, Sep 24, 2021
  13. 10/16 refs: add DO_FOR_EACH_OMIT_DANGLING_SYMREFS flagJeff King, Sep 24, 2021
  14. 11/16 refs: omit dangling symrefs when using GIT_REF_PARANOIAJeff King, Sep 24, 2021
  15. 12/16 refs: turn on GIT_REF_PARANOIA by defaultJeff King, Sep 24, 2021
  16. Jonathan TanSep 27, 2021
  17. 13/16 repack, prune: drop GIT_REF_PARANOIA settingsJeff King, Sep 24, 2021
  18. 14/16 ref-filter: stop setting FILTER_REFS_INCLUDE_BROKENJeff King, Sep 24, 2021
  19. 15/16 ref-filter: drop broken-ref code entirelyJeff King, Sep 24, 2021
  20. 16/16 refs: drop "broken" flag from for_each_fullref_in()Jeff King, Sep 24, 2021
  21. Jonathan TanSep 27, 2021
  22. Junio C HamanoSep 24, 2021

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.