From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: Taylor Blau <me@ttaylorr.com>
Cc: git@vger.kernel.org
Subject: Re: [RFC PATCH] for-each-ref: respect GIT_REF_PARANOIA setting
Date: Mon, 21 Mar 2022 18:29:38 +0100 [thread overview]
Message-ID: <220321.86wngn8arz.gmgdl@evledraar.gmail.com> (raw)
In-Reply-To: <7283f826198aaec94c847f0b26e228ace9a38433.1647880211.git.me@ttaylorr.com>
On Mon, Mar 21 2022, Taylor Blau wrote:
> When setting GIT_REF_PARANOIA=1 (which became the default in 968f12fdac
> (refs: turn on GIT_REF_PARANOIA by default, 2021-09-24)), `git
> for-each-ref` will display a warning when it encounters a broken ref,
> but does not terminate the program.
>
> This can result in somewhat surprising behavior like:
>
> $ echo bogus >.git/refs/heads/bogus
> $ GIT_REF_PARANOIA=1 git for-each-ref; echo "==> $?"
> warning: ignoring broken ref refs/heads/bogus
> ==> 0
>
> This seems to be the case even before the introduction of the ref-filter
> code via 7ebc8cbedd (Merge branch 'kn/for-each-ref', 2015-08-03).
> Looking at 8afc493d11 (for-each-ref: report broken references correctly,
> 2015-06-02) when this was last addressed, the fix at the time was to
> report any broken references, but this warning did not affect the
> command's success.
>
> It seems that `git for-each-ref` should exit non-zero in the case of a
> broken reference when GIT_REF_PARANOIA is set to 1. This patch does
> that, but there are a couple of open questions (hence its status as an
> RFC):
I started playing with this fix-up:
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index e1937b7e53e..05b7c9b2a69 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -78,8 +78,6 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
filter.name_patterns = argv;
filter.match_as_path = 1;
ret = filter_refs(&array, &filter, FILTER_REFS_ALL);
- if (ret)
- goto cleanup;
ref_array_sort(sorting, &array);
if (!maxcount || array.nr < maxcount)
@@ -93,7 +91,6 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
putchar('\n');
}
-cleanup:
strbuf_release(&err);
strbuf_release(&output);
ref_array_clear(&array);
diff --git a/t/t6301-for-each-ref-errors.sh b/t/t6301-for-each-ref-errors.sh
index 2a5895c124a..8a93685bb3e 100755
--- a/t/t6301-for-each-ref-errors.sh
+++ b/t/t6301-for-each-ref-errors.sh
@@ -19,7 +19,8 @@ test_expect_success 'Broken refs are reported correctly' '
: >.git/$r &&
test_when_finished "rm -f .git/$r" &&
echo "warning: ignoring broken ref $r" >broken-err &&
- test_must_fail git for-each-ref 2>err &&
+ test_must_fail git for-each-ref >out 2>err &&
+ test_must_be_empty out &&
test_cmp broken-err err
'
@@ -31,7 +32,11 @@ test_expect_success 'NULL_SHA1 refs are reported correctly' '
test_must_fail git for-each-ref 2>err &&
test_cmp zeros-err err &&
test_must_fail git for-each-ref --format="%(objectname) %(refname)" \
- 2>brief-err &&
+ >actual 2>brief-err &&
+ cat >expect <<-EOF &&
+ $(git rev-parse HEAD) $(git rev-parse --symbolic-full-name HEAD)
+ EOF
+ test_cmp expect actual &&
test_cmp zeros-err brief-err
'
It seems to me you'd want at least the part of it where we retain a
test_cmp or similar for the "out", rather than removing it completely.
> - First, there are a handful of other `filter_refs()` calls throughout
> the builtin tree that lack similar error handling. I suspect that
> these will need similar treatment, but I haven't looked at them
> deeply yet.
>
> - More pressing, though, is that there is some test fallout as a
> result of this change. Namely, t6301 expects that `git for-each-ref`
> should list out all of the non-broken references to stdout _even
> when broken references exist_.
>
> This patch changes that behavior and causes us to exit immediately,
> without printing out any of the non-broken references (since we are
> still building up the list of references to sort, and thus haven't
> printed anything out by the time we're in the ref_filter_handler
> callback).
>
> The test fallout can be seen in the changes to t6301, namely that we
> expect `for-each-ref` to fail in certain cases where it didn't
> before, and that in those cases we no longer guarantee the contents
> of stdout.
>
> The second point gives me serious pause about whether or not this change
> is the right one. So I'm curious if or how we should handle this case.
I think the right thing to do is to add a filter_refs() where we add
FILTER_REFS_WANT_REF_ISBROKEN and maybe FILTER_REFS_WANT_REF_BAD_NAME.
Then have in the for-each-ref.c loop check the "flags" on the ref item
for REF_ISBROKEN etc, and either have format_ref_array_item() format it,
or skip that and issue a warning() there manually.
That way API users can opt-in and detect these, but still be able to
print the rest, and it allows to make the more narrow change of amending
the exit code.
I'd think builtin/{tag,branch}.c would want similar treatment, ditto
fetch-pack.c.
But I really don't see why we'd want to abort the iteration early just
because we see one broken ref, that's after all per-ref issue, and we
don't need to abort the walk entirely to issue a warning() or to change
our exit code.
So that part of the patch really seems like it's in the wrong place to
me, and that we should always have for-each-ref try as hard as it can to
emit the output it can emit, even if we change the exit code due to a
broken ref.
next prev parent reply other threads:[~2022-03-21 17:40 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-21 16:30 [RFC PATCH] for-each-ref: respect GIT_REF_PARANOIA setting Taylor Blau
2022-03-21 17:29 ` Ævar Arnfjörð Bjarmason [this message]
2022-03-21 20:33 ` 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=220321.86wngn8arz.gmgdl@evledraar.gmail.com \
--to=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=me@ttaylorr.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).