ref-filter: move ahead-behind bases into used_atom

verify_ref_format() parses a ref-filter format string and stores
recognized items in the static array "used_atom".  For
"ahead-behind:<committish>" it stores the committish part in a
string_list member "bases" of struct ref_format.

ref_sorting_options() also parses bare ref-filter format items and
stores stores recognized ones in "used_atom" as well.  The committish
parts go to a dummy struct ref_format in parse_sorting_atom(), though,
and are leaked and forgotten.

If verify_ref_format() is called before ref_sorting_options(), like in
git for-each-ref, then all works well if the sort key is included in the
format string.  If it isn't then sorting cannot work as the committishes
are missing.

If ref_sorting_options() is called first, like in git branch, then we
have the additional issue that if the sort key is included in the format
string then filter_ahead_behind() can't see its committish, will not
generate any results for it and thus it will be expanded to an empty
string.

Fix those issues by replacing the string_list with a field in used_atom
for storing the committish.  This way it can be shared for handling both
ref-filter format strings and sorting options in the same command.

Reported-by: Ross Goldberg <ross.goldberg@gmail.com>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
René Scharfe
2025-01-18 18:11:34 +01:00
committed by Junio C Hamano
parent fbe8d3079d
commit 5e58db6575
4 changed files with 59 additions and 26 deletions

View File

@ -368,6 +368,34 @@ test_expect_success 'git branch --format with ahead-behind' '
test_cmp expect actual
'
test_expect_success 'git branch `--sort=[-]ahead-behind` option' '
cat >expect <<-\EOF &&
(HEAD detached from fromtag) 0 0
refs/heads/ambiguous 0 0
refs/heads/branch-two 0 0
refs/heads/branch-one 1 0
refs/heads/main 1 0
refs/heads/ref-to-branch 1 0
refs/heads/ref-to-remote 1 0
EOF
git branch --format="%(refname) %(ahead-behind:HEAD)" \
--sort=refname --sort=ahead-behind:HEAD >actual &&
test_cmp expect actual &&
cat >expect <<-\EOF &&
(HEAD detached from fromtag) 0 0
refs/heads/branch-one 1 0
refs/heads/main 1 0
refs/heads/ref-to-branch 1 0
refs/heads/ref-to-remote 1 0
refs/heads/ambiguous 0 0
refs/heads/branch-two 0 0
EOF
git branch --format="%(refname) %(ahead-behind:HEAD)" \
--sort=refname --sort=-ahead-behind:HEAD >actual &&
test_cmp expect actual
'
test_expect_success 'git branch with --format=%(rest) must fail' '
test_must_fail git branch --format="%(rest)" >actual
'