Skip to content

t1401: test symbolic-ref exit codes on a non-symbolic ref - #2204

Open
nikolauspschuetz wants to merge 1 commit into
gitgitgadget:masterfrom
nikolauspschuetz:ns/t1401-symbolic-ref-quiet
Open

t1401: test symbolic-ref exit codes on a non-symbolic ref#2204
nikolauspschuetz wants to merge 1 commit into
gitgitgadget:masterfrom
nikolauspschuetz:ns/t1401-symbolic-ref-quiet

Conversation

@nikolauspschuetz

@nikolauspschuetz nikolauspschuetz commented Aug 13, 2026

Copy link
Copy Markdown

git-symbolic-ref(1) documents that reading a name that is not a symbolic ref exits with a non-zero status, and that --quiet does so silently rather than printing a diagnostic. This exit-code contract was untested.

This adds two tests: querying a non-symbolic ref exits 128 with the usual "is not a symbolic ref" message, and --quiet instead exits 1 with no output.

Test-only; documents existing behaviour, in the spirit of 919eb8a (t1402: check for refs ending with a dot).

cc: Patrick Steinhardt ps@pks.im
cc: Phillip Wood phillip.wood123@gmail.com

@nikolauspschuetz
nikolauspschuetz marked this pull request as ready for review August 13, 2026 21:11
@nikolauspschuetz

Copy link
Copy Markdown
Author

/submit

@gitgitgadget

gitgitgadget Bot commented Aug 13, 2026

Copy link
Copy Markdown

Submitted as pull.2204.git.1786655554197.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-2204/nikolauspschuetz/ns/t1401-symbolic-ref-quiet-v1

To fetch this version to local tag pr-2204/nikolauspschuetz/ns/t1401-symbolic-ref-quiet-v1:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-2204/nikolauspschuetz/ns/t1401-symbolic-ref-quiet-v1

@nikolauspschuetz
nikolauspschuetz force-pushed the ns/t1401-symbolic-ref-quiet branch from 345e664 to fa9dd1d Compare August 13, 2026 21:37
@gitgitgadget

gitgitgadget Bot commented Aug 14, 2026

Copy link
Copy Markdown

This branch is now known as ns/ref-symref-additional-tests.

@gitgitgadget

gitgitgadget Bot commented Aug 14, 2026

Copy link
Copy Markdown

This patch series was integrated into seen via git@799dea8.

@gitgitgadget gitgitgadget Bot added the seen label Aug 14, 2026
@gitgitgadget

gitgitgadget Bot commented Aug 15, 2026

Copy link
Copy Markdown

There was a status update in the "New Topics" section about the branch ns/ref-symref-additional-tests on the Git mailing list:

A few additional tests.

Needs review.
source: <pull.2204.git.1786655554197.gitgitgadget@gmail.com>
source: <pull.2203.git.1786653837190.gitgitgadget@gmail.com>

@gitgitgadget

gitgitgadget Bot commented Aug 17, 2026

Copy link
Copy Markdown

There was a status update in the "Cooking" section about the branch ns/ref-symref-additional-tests on the Git mailing list:

A few additional tests.

Needs review.
source: <pull.2204.git.1786655554197.gitgitgadget@gmail.com>
source: <pull.2203.git.1786653837190.gitgitgadget@gmail.com>

@gitgitgadget

gitgitgadget Bot commented Aug 18, 2026

Copy link
Copy Markdown

There was a status update in the "Cooking" section about the branch ns/ref-symref-additional-tests on the Git mailing list:

A few additional tests.

Needs review.
source: <pull.2204.git.1786655554197.gitgitgadget@gmail.com>
source: <pull.2203.git.1786653837190.gitgitgadget@gmail.com>

@gitgitgadget

gitgitgadget Bot commented Aug 19, 2026

Copy link
Copy Markdown

Patrick Steinhardt wrote on the Git mailing list (how to reply to this email):

On Thu, Aug 13, 2026 at 09:12:33PM +0000, Nikolaus Schuetz via GitGitGadget wrote:
> From: Nikolaus Schuetz <nikolauspschuetz@gmail.com>
> 
> git-symbolic-ref(1) documents that reading a name that is not a
> symbolic ref exits with a non-zero status, and that --quiet does so
> silently rather than printing a diagnostic.  This was not tested.

Out of curiosity, what made you address these gaps in particular? Is
there any motivation, or are you just picking random things to work on?

> Check that querying a non-symbolic ref exits 128 with the usual
> "is not a symbolic ref" message, and that --quiet instead exits 1
> with no output.

This is testing the status quo, but what I think would be good to
research in this context is why the error codes are different in the
first place. I personally find that quite a bit puzzling, as my
expectation would be that "--quiet" really only impacts whether we print
anything or not. That it also changes the error code is weird.

> diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh
> index a2a7e94716..602db6d080 100755
> --- a/t/t1401-symbolic-ref.sh
> +++ b/t/t1401-symbolic-ref.sh
> @@ -38,6 +38,16 @@ test_expect_success 'symbolic-ref refuses bare sha1' '
>  
>  reset_to_sane
>  
> +test_expect_success 'symbolic-ref reports a non-symbolic ref with exit code 128' '
> +	test_expect_code 128 git symbolic-ref refs/heads/foo 2>err &&
> +	test_grep "is not a symbolic ref" err
> +'
> +
> +test_expect_success 'symbolic-ref -q is silent and exits 1 on a non-symbolic ref' '
> +	test_expect_code 1 git symbolic-ref -q refs/heads/foo 2>err &&
> +	test_must_be_empty err
> +'

Do we also want to verify that stdout is empty in both cases?

Thanks!

Patrick

@gitgitgadget

gitgitgadget Bot commented Aug 19, 2026

Copy link
Copy Markdown

User Patrick Steinhardt <ps@pks.im> has been added to the cc: list.

@nikolauspschuetz
nikolauspschuetz force-pushed the ns/t1401-symbolic-ref-quiet branch from fa9dd1d to 22694da Compare August 19, 2026 14:12
@gitgitgadget

gitgitgadget Bot commented Aug 20, 2026

Copy link
Copy Markdown

Nikolaus Schuetz wrote on the Git mailing list (how to reply to this email):

> Out of curiosity, what made you address these gaps in particular? Is
> there any motivation, or are you just picking random things to work on?

Not random -- I've been going through git commands, checking whether the
behavior their man pages promise is actually exercised from t/, and
filling the gaps. The idea is to pin the documented contract in a test so
a later refactor can't quietly change it. git-symbolic-ref(1) spells out
both the exit status and the --quiet silence, but neither was tested, so
they stood out.

> This is testing the status quo, but what I think would be good to
> research in this context is why the error codes are different in the
> first place.

Agreed it's surprising, though it's not unique to symbolic-ref: git
rev-parse --verify --quiet does the same thing (exit 1 and silent, vs a
fatal 128 without --quiet). It falls out of how the two paths report in
check_symref() (builtin/symbolic-ref.c): the non-quiet path calls die(),
which always exits 128, while --quiet can't die() -- that would print --
so it returns 1.

> Do we also want to verify that stdout is empty in both cases?

Great idea. I've revised the added tests to redirect stdout and check
for empty stdout in both cases.

Thanks,
Nikolaus

@nikolauspschuetz

Copy link
Copy Markdown
Author

/submit

@gitgitgadget

gitgitgadget Bot commented Aug 20, 2026

Copy link
Copy Markdown

Submitted as pull.2204.v2.git.1787264402361.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-2204/nikolauspschuetz/ns/t1401-symbolic-ref-quiet-v2

To fetch this version to local tag pr-2204/nikolauspschuetz/ns/t1401-symbolic-ref-quiet-v2:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-2204/nikolauspschuetz/ns/t1401-symbolic-ref-quiet-v2

@gitgitgadget

gitgitgadget Bot commented Aug 21, 2026

Copy link
Copy Markdown

There was a status update in the "Cooking" section about the branch ns/ref-symref-additional-tests on the Git mailing list:

A few additional tests.

Expecting a reroll.
cf. <20260820151325.58087-1-nikolauspschuetz@gmail.com>
cf. <20260820144648.47267-1-nikolauspschuetz@gmail.com>
source: <pull.2204.git.1786655554197.gitgitgadget@gmail.com>
source: <pull.2203.git.1786653837190.gitgitgadget@gmail.com>

@gitgitgadget

gitgitgadget Bot commented Aug 24, 2026

Copy link
Copy Markdown

This patch series is no longer integrated into seen.

@gitgitgadget gitgitgadget Bot removed the seen label Aug 24, 2026
@gitgitgadget

gitgitgadget Bot commented Aug 24, 2026

Copy link
Copy Markdown

There was a status update in the "Cooking" section about the branch ns/ref-symref-additional-tests on the Git mailing list:

A few additional tests.

Waiting for response.
cf. <xmqq5x13stxt.fsf@gitster.g>
source: <pull.2203.v2.git.1787264417682.gitgitgadget@gmail.com>
source: <pull.2204.v2.git.1787264402361.gitgitgadget@gmail.com>

@gitgitgadget

gitgitgadget Bot commented Aug 24, 2026

Copy link
Copy Markdown

This patch series was integrated into seen via git@a426bf9.

@gitgitgadget gitgitgadget Bot added the seen label Aug 24, 2026
@gitgitgadget

gitgitgadget Bot commented Aug 24, 2026

Copy link
Copy Markdown

Patrick Steinhardt wrote on the Git mailing list (how to reply to this email):

On Thu, Aug 20, 2026 at 10:20:02PM +0000, Nikolaus Schuetz via GitGitGadget wrote:
> From: Nikolaus Schuetz <nikolauspschuetz@gmail.com>
> 
> git-symbolic-ref(1) documents that reading a name that is not a
> symbolic ref exits non-zero, and that --quiet does so silently.
> Tests such as t2020 and t5621 already rely on "symbolic-ref -q HEAD"
> failing on a detached HEAD, but none pins the exact exit codes or
> checks that --quiet actually suppresses the diagnostic.
> 
> Assert that a non-symbolic ref exits 128 with the "is not a symbolic
> ref" message, and that --quiet instead exits 1 with no output.

I'm still not completely sold that this difference is intentional. As
you mentioned elsewhere, in one code path we use `exit(1)` and in the
other we use `die(...)` to print an error message, which returs 128. But
that to me feels more like nobody noticed that those return different
error codes rather than an intentional difference in design, so casting
that behaviour into stone with new tests feels wrong to me.

I'd suggest that we either:

  - Continue not checking for the exact error code.

  - Adapt the `exit(1)` to instead be `die(NULL)` so that we have the
    same error code across both code paths and then verify that both
    have the same error code.

Thanks!

Patrick

@gitgitgadget

gitgitgadget Bot commented Aug 24, 2026

Copy link
Copy Markdown

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

Patrick Steinhardt <ps@pks.im> writes:

> I'm still not completely sold that this difference is intentional. As
> you mentioned elsewhere, in one code path we use `exit(1)` and in the
> other we use `die(...)` to print an error message, which returs 128. But
> that to me feels more like nobody noticed that those return different
> error codes rather than an intentional difference in design, so casting
> that behaviour into stone with new tests feels wrong to me.

I tend to agree.  The choice of 1 would have been more about "we
need to exit with non-zero status" than "we need to use something
different from what is used by die()".

> I'd suggest that we either:
>
>   - Continue not checking for the exact error code.
>
>   - Adapt the `exit(1)` to instead be `die(NULL)` so that we have the
>     same error code across both code paths and then verify that both
>     have the same error code.

Both sounds very sensible.

Especially the former to avoid overspecifying what does not matter
in the end.

Thanks.

@gitgitgadget

gitgitgadget Bot commented Aug 24, 2026

Copy link
Copy Markdown

Phillip Wood wrote on the Git mailing list (how to reply to this email):

On 24/08/2026 19:23, Junio C Hamano wrote:
> Patrick Steinhardt <ps@pks.im> writes:
> >> I'm still not completely sold that this difference is intentional. As
>> you mentioned elsewhere, in one code path we use `exit(1)` and in the
>> other we use `die(...)` to print an error message, which returs 128. But
>> that to me feels more like nobody noticed that those return different
>> error codes rather than an intentional difference in design, so casting
>> that behaviour into stone with new tests feels wrong to me.
> > I tend to agree.  The choice of 1 would have been more about "we
> need to exit with non-zero status" than "we need to use something
> different from what is used by die()".

I'd always assumed the difference was to allow scripts to distinguish between an invalid option and the ref not existing, like "git rev-parse --quiet --verify" and "git show-ref --quiet --verify".

Thanks

Phillip

> >> I'd suggest that we either:
>>
>>    - Continue not checking for the exact error code.
>>
>>    - Adapt the `exit(1)` to instead be `die(NULL)` so that we have the
>>      same error code across both code paths and then verify that both
>>      have the same error code.
> > Both sounds very sensible.
> > Especially the former to avoid overspecifying what does not matter
> in the end.
> > Thanks.
> 

@gitgitgadget

gitgitgadget Bot commented Aug 24, 2026

Copy link
Copy Markdown

User Phillip Wood <phillip.wood123@gmail.com> has been added to the cc: list.

@gitgitgadget

gitgitgadget Bot commented Aug 24, 2026

Copy link
Copy Markdown

Nikolaus Schuetz wrote on the Git mailing list (how to reply to this email):

I would favor continuing to not test for the exact error code, and
would rather not disturb anything scripts may already rely on.

In either case the git-symbolic-ref.adoc NOTES are out of sync with the
actual behavior:

  'git symbolic-ref' will exit with status 0 [...], with status 1 if the
  requested name is not a symbolic ref, or 128 if another error occurs.

To describe the actual behavior:

  'git symbolic-ref' will exit with status 0 if the contents of the
  symbolic ref were printed correctly, with status 1 if the requested
  name is not a symbolic ref and --quiet was given, or with status 128
  if it is not a symbolic ref and --quiet was not given, or another
  error occurs.

If that sounds OK I can update the adoc and call it good.

Thanks,
Nikolaus

@gitgitgadget

gitgitgadget Bot commented Aug 25, 2026

Copy link
Copy Markdown

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

Nikolaus Schuetz <nikolauspschuetz@gmail.com> writes:

> I would favor continuing to not test for the exact error code, and
> would rather not disturb anything scripts may already rely on.
>
> In either case the git-symbolic-ref.adoc NOTES are out of sync with the
> actual behavior:
>
>   'git symbolic-ref' will exit with status 0 [...], with status 1 if the
>   requested name is not a symbolic ref, or 128 if another error occurs.
>
> To describe the actual behavior:
>
>   'git symbolic-ref' will exit with status 0 if the contents of the
>   symbolic ref were printed correctly, with status 1 if the requested
>   name is not a symbolic ref and --quiet was given, or with status 128
>   if it is not a symbolic ref and --quiet was not given, or another
>   error occurs.
>
> If that sounds OK I can update the adoc and call it good.

This is the kind of "casting wrong behaviour into stone by either
documentation or tests" that I advised against in my earlier
message.

…ic ref

git-symbolic-ref(1) documents that reading a name that is not a
symbolic ref fails, and that --quiet does so silently.  Tests such as
t2020 and t5621 already rely on "symbolic-ref -q HEAD" failing on a
detached HEAD, but none checks that the plain form reports the error
or that --quiet stays silent.

Assert that a non-symbolic ref fails with the "is not a symbolic ref"
message, and that --quiet fails with no output.  Use test_must_fail
rather than pinning the exact exit codes, which are documented but not
worth freezing in the test.

Signed-off-by: Nikolaus Schuetz <nikolauspschuetz@gmail.com>
@nikolauspschuetz
nikolauspschuetz force-pushed the ns/t1401-symbolic-ref-quiet branch from 22694da to 0391dcc Compare August 26, 2026 16:50
@nikolauspschuetz

Copy link
Copy Markdown
Author

/submit

@gitgitgadget

gitgitgadget Bot commented Aug 26, 2026

Copy link
Copy Markdown

Submitted as pull.2204.v3.git.1787763107646.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-2204/nikolauspschuetz/ns/t1401-symbolic-ref-quiet-v3

To fetch this version to local tag pr-2204/nikolauspschuetz/ns/t1401-symbolic-ref-quiet-v3:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-2204/nikolauspschuetz/ns/t1401-symbolic-ref-quiet-v3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant