2015-07-09 06:03:21 +00:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='test for-each-refs usage of ref-filter APIs'
|
|
|
|
|
|
|
|
. ./test-lib.sh
|
|
|
|
. "$TEST_DIRECTORY"/lib-gpg.sh
|
|
|
|
|
|
|
|
test_expect_success 'setup some history and refs' '
|
|
|
|
test_commit one &&
|
2020-12-17 01:07:08 +00:00
|
|
|
git branch -M main &&
|
2015-07-09 06:03:21 +00:00
|
|
|
test_commit two &&
|
|
|
|
test_commit three &&
|
|
|
|
git checkout -b side &&
|
|
|
|
test_commit four &&
|
2016-03-07 00:10:26 +00:00
|
|
|
git tag -m "An annotated tag" annotated-tag &&
|
|
|
|
git tag -m "Annonated doubly" doubly-annotated-tag annotated-tag &&
|
2016-05-09 16:49:00 +00:00
|
|
|
|
|
|
|
# Note that these "signed" tags might not actually be signed.
|
|
|
|
# Tests which care about the distinction should be marked
|
|
|
|
# with the GPG prereq.
|
2016-03-07 00:10:27 +00:00
|
|
|
if test_have_prereq GPG
|
|
|
|
then
|
2016-05-09 16:49:00 +00:00
|
|
|
sign=-s
|
|
|
|
else
|
|
|
|
sign=
|
2016-03-07 00:10:27 +00:00
|
|
|
fi &&
|
2016-05-09 16:49:00 +00:00
|
|
|
git tag $sign -m "A signed tag" signed-tag &&
|
|
|
|
git tag $sign -m "Signed doubly" doubly-signed-tag signed-tag &&
|
|
|
|
|
2020-12-17 01:07:08 +00:00
|
|
|
git checkout main &&
|
|
|
|
git update-ref refs/odd/spot main
|
2015-07-09 06:03:21 +00:00
|
|
|
'
|
|
|
|
|
2024-02-23 10:01:12 +00:00
|
|
|
test_expect_success '--include-root-refs pattern prints pseudorefs' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
HEAD
|
|
|
|
ORIG_HEAD
|
|
|
|
refs/heads/main
|
|
|
|
refs/heads/side
|
|
|
|
refs/odd/spot
|
|
|
|
refs/tags/annotated-tag
|
|
|
|
refs/tags/doubly-annotated-tag
|
|
|
|
refs/tags/doubly-signed-tag
|
|
|
|
refs/tags/four
|
|
|
|
refs/tags/one
|
|
|
|
refs/tags/signed-tag
|
|
|
|
refs/tags/three
|
|
|
|
refs/tags/two
|
|
|
|
EOF
|
|
|
|
git update-ref ORIG_HEAD main &&
|
|
|
|
git for-each-ref --format="%(refname)" --include-root-refs >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2024-05-15 06:51:01 +00:00
|
|
|
test_expect_success '--include-root-refs pattern does not print special refs' '
|
|
|
|
test_when_finished "rm -rf repo" &&
|
|
|
|
git init repo &&
|
|
|
|
(
|
|
|
|
cd repo &&
|
|
|
|
test_commit initial &&
|
|
|
|
git rev-parse HEAD >.git/MERGE_HEAD &&
|
|
|
|
git for-each-ref --format="%(refname)" --include-root-refs >actual &&
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
HEAD
|
|
|
|
$(git symbolic-ref HEAD)
|
|
|
|
refs/tags/initial
|
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2024-02-23 10:01:12 +00:00
|
|
|
test_expect_success '--include-root-refs with other patterns' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
HEAD
|
|
|
|
ORIG_HEAD
|
|
|
|
EOF
|
|
|
|
git update-ref ORIG_HEAD main &&
|
|
|
|
git for-each-ref --format="%(refname)" --include-root-refs "*HEAD" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
refs: do not check ref existence in `is_root_ref()`
Before this patch series, root refs except for "HEAD" and our special
refs were classified as pseudorefs. Furthermore, our terminology
clarified that pseudorefs must not be symbolic refs. This restriction
is enforced in `is_root_ref()`, which explicitly checks that a supposed
root ref resolves to an object ID without recursing.
This has been extremely confusing right from the start because (in old
terminology) a ref name may sometimes be a pseudoref and sometimes not
depending on whether it is a symbolic or regular ref. This behaviour
does not seem reasonable at all and I very much doubt that it results in
anything sane.
Last but not least, the current behaviour can actually lead to a
segfault when calling `is_root_ref()` with a reference that either does
not exist or that is a symbolic ref because we never initialized `oid`,
but then read it via `is_null_oid()`.
We have now changed terminology to clarify that pseudorefs are really
only "MERGE_HEAD" and "FETCH_HEAD", whereas all the other refs that live
in the root of the ref hierarchy are just plain refs. Thus, we do not
need to check whether the ref is symbolic or not. In fact, we can now
avoid looking up the ref completely as the name is sufficient for us to
figure out whether something would be a root ref or not.
This change of course changes semantics for our callers. As there are
only three of them we can assess each of them individually:
- "ref-filter.c:ref_kind_from_refname()" uses it to classify refs.
It's clear that the intent is to classify based on the ref name,
only.
- "refs/reftable_backend.c:reftable_ref_iterator_advance()" uses it to
filter root refs. Again, using existence checks is pointless here as
the iterator has just surfaced the ref, so we know it does exist.
- "refs/files_backend.c:add_pseudoref_and_head_entries()" uses it to
determine whether it should add a ref to the root directory of its
iterator. This had the effect that we skipped over any files that
are either a symbolic ref, or which are not a ref at all.
The new behaviour is to include symbolic refs know, which aligns us
with the adapted terminology. Furthermore, files which look like
root refs but aren't are now mark those as "broken". As broken refs
are not surfaced by our tooling, this should not lead to a change in
user-visible behaviour, but may cause us to emit warnings. This
feels like the right thing to do as we would otherwise just silently
ignore corrupted root refs completely.
So in all cases the existence check was either superfluous, not in line
with the adapted terminology or masked potential issues. This commit
thus changes the behaviour as proposed and drops the existence check
altogether.
Add a test that verifies that this does not change user-visible
behaviour. Namely, we still don't want to show broken refs to the user
by default in git-for-each-ref(1). What this does allow though is for
internal callers to surface dangling root refs when they pass in the
`DO_FOR_EACH_INCLUDE_BROKEN` flag.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-05-15 06:50:51 +00:00
|
|
|
test_expect_success '--include-root-refs omits dangling symrefs' '
|
|
|
|
test_when_finished "rm -rf repo" &&
|
|
|
|
git init repo &&
|
|
|
|
(
|
|
|
|
cd repo &&
|
|
|
|
test_commit initial &&
|
|
|
|
git symbolic-ref DANGLING_HEAD refs/heads/missing &&
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
HEAD
|
|
|
|
$(git symbolic-ref HEAD)
|
|
|
|
refs/tags/initial
|
|
|
|
EOF
|
|
|
|
git for-each-ref --format="%(refname)" --include-root-refs >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2015-07-07 16:06:10 +00:00
|
|
|
test_expect_success 'filtering with --points-at' '
|
|
|
|
cat >expect <<-\EOF &&
|
2020-12-17 01:07:08 +00:00
|
|
|
refs/heads/main
|
2015-07-07 16:06:10 +00:00
|
|
|
refs/odd/spot
|
|
|
|
refs/tags/three
|
|
|
|
EOF
|
2020-12-17 01:07:08 +00:00
|
|
|
git for-each-ref --format="%(refname)" --points-at=main >actual &&
|
2015-07-07 16:06:10 +00:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'check signed tags with --points-at' '
|
2016-05-09 16:49:00 +00:00
|
|
|
sed -e "s/Z$//" >expect <<-\EOF &&
|
2015-07-07 16:06:10 +00:00
|
|
|
refs/heads/side Z
|
2016-03-07 00:10:26 +00:00
|
|
|
refs/tags/annotated-tag four
|
ref-filter.c: use peeled tag for '*' format fields
In most builtins ('rev-parse <revision>^{}', 'show-ref --dereference'),
"dereferencing" a tag refers to a recursive peel of the tag object. Unlike
these cases, the dereferencing prefix ('*') in 'for-each-ref' format
specifiers triggers only a single, non-recursive dereference of a given tag
object. For most annotated tags, a single dereference is all that is needed
to access the tag's associated commit or tree; "recursive" and
"non-recursive" dereferencing are functionally equivalent in these cases.
However, nested tags (annotated tags whose target is another annotated tag)
dereferenced once return another tag, where a recursive dereference would
return the commit or tree.
Currently, if a user wants to filter & format refs and include information
about a recursively-dereferenced tag, they can do so with something like
'cat-file --batch-check':
git for-each-ref --format="%(objectname)^{} %(refname)" <pattern> |
git cat-file --batch-check="%(objectname) %(rest)"
But the combination of commands is inefficient. So, to improve the
performance of this use case and align the defererencing behavior of
'for-each-ref' with that of other commands, update the ref formatting code
to use the peeled tag (from 'peel_iterated_oid()') to populate '*' fields
rather than the tag's immediate target object (from 'get_tagged_oid()').
Additionally, add a test to 't6300-for-each-ref' to verify new nested tag
behavior and update 't6302-for-each-ref-filter.sh' to print the correct
value for nested dereferenced fields.
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-14 19:53:57 +00:00
|
|
|
refs/tags/doubly-annotated-tag four
|
|
|
|
refs/tags/doubly-signed-tag four
|
2015-07-07 16:06:10 +00:00
|
|
|
refs/tags/four Z
|
|
|
|
refs/tags/signed-tag four
|
|
|
|
EOF
|
|
|
|
git for-each-ref --format="%(refname) %(*subject)" --points-at=side >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2015-07-07 16:06:13 +00:00
|
|
|
test_expect_success 'filtering with --merged' '
|
|
|
|
cat >expect <<-\EOF &&
|
2020-12-17 01:07:08 +00:00
|
|
|
refs/heads/main
|
2015-07-07 16:06:13 +00:00
|
|
|
refs/odd/spot
|
|
|
|
refs/tags/one
|
|
|
|
refs/tags/three
|
|
|
|
refs/tags/two
|
|
|
|
EOF
|
2020-12-17 01:07:08 +00:00
|
|
|
git for-each-ref --format="%(refname)" --merged=main >actual &&
|
2015-07-07 16:06:13 +00:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'filtering with --no-merged' '
|
2016-05-09 16:49:00 +00:00
|
|
|
cat >expect <<-\EOF &&
|
2015-07-07 16:06:13 +00:00
|
|
|
refs/heads/side
|
2016-03-07 00:10:26 +00:00
|
|
|
refs/tags/annotated-tag
|
|
|
|
refs/tags/doubly-annotated-tag
|
2016-03-07 00:10:25 +00:00
|
|
|
refs/tags/doubly-signed-tag
|
2015-07-07 16:06:13 +00:00
|
|
|
refs/tags/four
|
|
|
|
refs/tags/signed-tag
|
|
|
|
EOF
|
2020-12-17 01:07:08 +00:00
|
|
|
git for-each-ref --format="%(refname)" --no-merged=main >actual &&
|
2015-07-07 16:06:13 +00:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2015-07-07 16:06:17 +00:00
|
|
|
test_expect_success 'filtering with --contains' '
|
2016-05-09 16:49:00 +00:00
|
|
|
cat >expect <<-\EOF &&
|
2020-12-17 01:07:08 +00:00
|
|
|
refs/heads/main
|
2015-07-07 16:06:17 +00:00
|
|
|
refs/heads/side
|
|
|
|
refs/odd/spot
|
2016-03-07 00:10:26 +00:00
|
|
|
refs/tags/annotated-tag
|
|
|
|
refs/tags/doubly-annotated-tag
|
2016-03-07 00:10:25 +00:00
|
|
|
refs/tags/doubly-signed-tag
|
2015-07-07 16:06:17 +00:00
|
|
|
refs/tags/four
|
|
|
|
refs/tags/signed-tag
|
|
|
|
refs/tags/three
|
|
|
|
refs/tags/two
|
|
|
|
EOF
|
|
|
|
git for-each-ref --format="%(refname)" --contains=two >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
ref-filter: add --no-contains option to tag/branch/for-each-ref
Change the tag, branch & for-each-ref commands to have a --no-contains
option in addition to their longstanding --contains options.
This allows for finding the last-good rollout tag given a known-bad
<commit>. Given a hypothetically bad commit cf5c7253e0, the git
version to revert to can be found with this hacky two-liner:
(git tag -l 'v[0-9]*'; git tag -l --contains cf5c7253e0 'v[0-9]*') |
sort | uniq -c | grep -E '^ *1 ' | awk '{print $2}' | tail -n 10
With this new --no-contains option the same can be achieved with:
git tag -l --no-contains cf5c7253e0 'v[0-9]*' | sort | tail -n 10
As the filtering machinery is shared between the tag, branch &
for-each-ref commands, implement this for those commands too. A
practical use for this with "branch" is e.g. finding branches which
were branched off between v2.8.0 and v2.10.0:
git branch --contains v2.8.0 --no-contains v2.10.0
The "describe" command also has a --contains option, but its semantics
are unrelated to what tag/branch/for-each-ref use --contains for. A
--no-contains option for "describe" wouldn't make any sense, other
than being exactly equivalent to not supplying --contains at all,
which would be confusing at best.
Add a --without option to "tag" as an alias for --no-contains, for
consistency with --with and --contains. The --with option is
undocumented, and possibly the only user of it is
Junio (<xmqqefy71iej.fsf@gitster.mtv.corp.google.com>). But it's
trivial to support, so let's do that.
The additions to the the test suite are inverse copies of the
corresponding --contains tests. With this change --no-contains for
tag, branch & for-each-ref is just as well tested as the existing
--contains option.
In addition to those tests, add a test for "tag" which asserts that
--no-contains won't find tree/blob tags, which is slightly
unintuitive, but consistent with how --contains works & is documented.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-24 18:40:57 +00:00
|
|
|
test_expect_success 'filtering with --no-contains' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
refs/tags/one
|
|
|
|
EOF
|
|
|
|
git for-each-ref --format="%(refname)" --no-contains=two >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'filtering with --contains and --no-contains' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
refs/tags/two
|
|
|
|
EOF
|
|
|
|
git for-each-ref --format="%(refname)" --contains=two --no-contains=three >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2015-09-11 14:59:47 +00:00
|
|
|
test_expect_success '%(color) must fail' '
|
|
|
|
test_must_fail git for-each-ref --format="%(color)%(refname)"
|
|
|
|
'
|
|
|
|
|
2021-05-11 15:35:20 +00:00
|
|
|
test_expect_success '%(color:#aa22ac) must succeed' '
|
|
|
|
test_when_finished rm -rf test &&
|
|
|
|
git init test &&
|
|
|
|
(
|
|
|
|
cd test &&
|
|
|
|
test_commit initial &&
|
|
|
|
git branch -M main &&
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
refs/heads/main
|
|
|
|
refs/tags/initial
|
|
|
|
EOF
|
|
|
|
git remote add origin nowhere &&
|
|
|
|
git config branch.main.remote origin &&
|
|
|
|
git config branch.main.merge refs/heads/main &&
|
|
|
|
git for-each-ref --format="%(color:#aa22ac)%(refname)" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2020-12-17 01:07:08 +00:00
|
|
|
test_expect_success 'left alignment is default' '
|
2016-05-09 16:49:00 +00:00
|
|
|
cat >expect <<-\EOF &&
|
2020-10-23 14:00:05 +00:00
|
|
|
refname is refs/heads/main |refs/heads/main
|
2015-09-11 15:03:07 +00:00
|
|
|
refname is refs/heads/side |refs/heads/side
|
|
|
|
refname is refs/odd/spot |refs/odd/spot
|
2016-03-07 00:10:26 +00:00
|
|
|
refname is refs/tags/annotated-tag|refs/tags/annotated-tag
|
|
|
|
refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
|
2016-03-07 00:10:25 +00:00
|
|
|
refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
|
2015-09-11 15:03:07 +00:00
|
|
|
refname is refs/tags/four |refs/tags/four
|
|
|
|
refname is refs/tags/one |refs/tags/one
|
|
|
|
refname is refs/tags/signed-tag|refs/tags/signed-tag
|
|
|
|
refname is refs/tags/three |refs/tags/three
|
|
|
|
refname is refs/tags/two |refs/tags/two
|
|
|
|
EOF
|
|
|
|
git for-each-ref --format="%(align:30)refname is %(refname)%(end)|%(refname)" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2020-12-17 01:07:08 +00:00
|
|
|
test_expect_success 'middle alignment' '
|
2016-05-09 16:49:00 +00:00
|
|
|
cat >expect <<-\EOF &&
|
2020-10-23 14:00:05 +00:00
|
|
|
| refname is refs/heads/main |refs/heads/main
|
2015-09-11 15:03:07 +00:00
|
|
|
| refname is refs/heads/side |refs/heads/side
|
|
|
|
| refname is refs/odd/spot |refs/odd/spot
|
2016-03-07 00:10:26 +00:00
|
|
|
|refname is refs/tags/annotated-tag|refs/tags/annotated-tag
|
|
|
|
|refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
|
2016-03-07 00:10:25 +00:00
|
|
|
|refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
|
2015-09-11 15:03:07 +00:00
|
|
|
| refname is refs/tags/four |refs/tags/four
|
|
|
|
| refname is refs/tags/one |refs/tags/one
|
|
|
|
|refname is refs/tags/signed-tag|refs/tags/signed-tag
|
|
|
|
| refname is refs/tags/three |refs/tags/three
|
|
|
|
| refname is refs/tags/two |refs/tags/two
|
|
|
|
EOF
|
|
|
|
git for-each-ref --format="|%(align:middle,30)refname is %(refname)%(end)|%(refname)" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2020-12-17 01:07:08 +00:00
|
|
|
test_expect_success 'right alignment' '
|
2016-05-09 16:49:00 +00:00
|
|
|
cat >expect <<-\EOF &&
|
2020-10-23 14:00:05 +00:00
|
|
|
| refname is refs/heads/main|refs/heads/main
|
2015-09-11 15:03:07 +00:00
|
|
|
| refname is refs/heads/side|refs/heads/side
|
|
|
|
| refname is refs/odd/spot|refs/odd/spot
|
2016-03-07 00:10:26 +00:00
|
|
|
|refname is refs/tags/annotated-tag|refs/tags/annotated-tag
|
|
|
|
|refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
|
2016-03-07 00:10:25 +00:00
|
|
|
|refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
|
2015-09-11 15:03:07 +00:00
|
|
|
| refname is refs/tags/four|refs/tags/four
|
|
|
|
| refname is refs/tags/one|refs/tags/one
|
|
|
|
|refname is refs/tags/signed-tag|refs/tags/signed-tag
|
|
|
|
| refname is refs/tags/three|refs/tags/three
|
|
|
|
| refname is refs/tags/two|refs/tags/two
|
|
|
|
EOF
|
|
|
|
git for-each-ref --format="|%(align:30,right)refname is %(refname)%(end)|%(refname)" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2016-05-09 16:49:00 +00:00
|
|
|
cat >expect <<-\EOF
|
2020-10-23 14:00:05 +00:00
|
|
|
| refname is refs/heads/main |refs/heads/main
|
2016-02-17 18:06:16 +00:00
|
|
|
| refname is refs/heads/side |refs/heads/side
|
|
|
|
| refname is refs/odd/spot |refs/odd/spot
|
2016-03-07 00:10:26 +00:00
|
|
|
| refname is refs/tags/annotated-tag |refs/tags/annotated-tag
|
|
|
|
|refname is refs/tags/doubly-annotated-tag |refs/tags/doubly-annotated-tag
|
2016-03-07 00:10:25 +00:00
|
|
|
| refname is refs/tags/doubly-signed-tag |refs/tags/doubly-signed-tag
|
2016-02-17 18:06:16 +00:00
|
|
|
| refname is refs/tags/four |refs/tags/four
|
|
|
|
| refname is refs/tags/one |refs/tags/one
|
|
|
|
| refname is refs/tags/signed-tag |refs/tags/signed-tag
|
|
|
|
| refname is refs/tags/three |refs/tags/three
|
|
|
|
| refname is refs/tags/two |refs/tags/two
|
|
|
|
EOF
|
|
|
|
|
|
|
|
test_align_permutations() {
|
|
|
|
while read -r option
|
|
|
|
do
|
2020-12-17 01:07:08 +00:00
|
|
|
test_expect_success "align:$option" '
|
2016-02-17 18:06:16 +00:00
|
|
|
git for-each-ref --format="|%(align:$option)refname is %(refname)%(end)|%(refname)" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
test_align_permutations <<-\EOF
|
|
|
|
middle,42
|
|
|
|
42,middle
|
|
|
|
position=middle,42
|
|
|
|
42,position=middle
|
|
|
|
middle,width=42
|
|
|
|
width=42,middle
|
|
|
|
position=middle,width=42
|
|
|
|
width=42,position=middle
|
|
|
|
EOF
|
|
|
|
|
|
|
|
# Last one wins (silently) when multiple arguments of the same type are given
|
|
|
|
|
|
|
|
test_align_permutations <<-\EOF
|
|
|
|
32,width=42,middle
|
|
|
|
width=30,42,middle
|
|
|
|
width=42,position=right,middle
|
|
|
|
42,right,position=middle
|
|
|
|
EOF
|
|
|
|
|
2015-09-11 15:03:07 +00:00
|
|
|
# Individual atoms inside %(align:...) and %(end) must not be quoted.
|
|
|
|
|
2020-12-17 01:07:08 +00:00
|
|
|
test_expect_success 'alignment with format quote' "
|
2016-05-09 16:49:00 +00:00
|
|
|
cat >expect <<-\EOF &&
|
2020-10-23 14:00:05 +00:00
|
|
|
|' '\''main| A U Thor'\'' '|
|
2015-09-11 15:03:07 +00:00
|
|
|
|' '\''side| A U Thor'\'' '|
|
|
|
|
|' '\''odd/spot| A U Thor'\'' '|
|
2016-03-07 00:10:26 +00:00
|
|
|
|' '\''annotated-tag| '\'' '|
|
|
|
|
|' '\''doubly-annotated-tag| '\'' '|
|
2016-03-07 00:10:25 +00:00
|
|
|
|' '\''doubly-signed-tag| '\'' '|
|
2015-09-11 15:03:07 +00:00
|
|
|
|' '\''four| A U Thor'\'' '|
|
|
|
|
|' '\''one| A U Thor'\'' '|
|
|
|
|
|' '\''signed-tag| '\'' '|
|
|
|
|
|' '\''three| A U Thor'\'' '|
|
|
|
|
|' '\''two| A U Thor'\'' '|
|
|
|
|
EOF
|
|
|
|
git for-each-ref --shell --format=\"|%(align:30,middle)'%(refname:short)| %(authorname)'%(end)|\" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
"
|
|
|
|
|
2020-12-17 01:07:08 +00:00
|
|
|
test_expect_success 'nested alignment with quote formatting' "
|
2016-05-09 16:49:00 +00:00
|
|
|
cat >expect <<-\EOF &&
|
2020-10-23 14:00:05 +00:00
|
|
|
|' main '|
|
2015-09-11 15:03:07 +00:00
|
|
|
|' side '|
|
|
|
|
|' odd/spot '|
|
2016-03-07 00:10:26 +00:00
|
|
|
|' annotated-tag '|
|
|
|
|
|'doubly-annotated-tag '|
|
2016-03-07 00:10:25 +00:00
|
|
|
|'doubly-signed-tag '|
|
2015-09-11 15:03:07 +00:00
|
|
|
|' four '|
|
|
|
|
|' one '|
|
|
|
|
|' signed-tag '|
|
|
|
|
|' three '|
|
|
|
|
|' two '|
|
|
|
|
EOF
|
|
|
|
git for-each-ref --shell --format='|%(align:30,left)%(align:15,right)%(refname:short)%(end)%(end)|' >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
"
|
|
|
|
|
2015-09-11 15:04:16 +00:00
|
|
|
test_expect_success 'check `%(contents:lines=1)`' '
|
2016-05-09 16:49:00 +00:00
|
|
|
cat >expect <<-\EOF &&
|
2020-12-17 01:07:08 +00:00
|
|
|
main |three
|
2015-09-11 15:04:16 +00:00
|
|
|
side |four
|
|
|
|
odd/spot |three
|
2016-03-07 00:10:26 +00:00
|
|
|
annotated-tag |An annotated tag
|
|
|
|
doubly-annotated-tag |Annonated doubly
|
2016-03-07 00:10:25 +00:00
|
|
|
doubly-signed-tag |Signed doubly
|
2015-09-11 15:04:16 +00:00
|
|
|
four |four
|
|
|
|
one |one
|
2016-03-07 00:10:25 +00:00
|
|
|
signed-tag |A signed tag
|
2015-09-11 15:04:16 +00:00
|
|
|
three |three
|
|
|
|
two |two
|
|
|
|
EOF
|
|
|
|
git for-each-ref --format="%(refname:short) |%(contents:lines=1)" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'check `%(contents:lines=0)`' '
|
2016-05-09 16:49:00 +00:00
|
|
|
cat >expect <<-\EOF &&
|
2020-12-17 01:07:08 +00:00
|
|
|
main |
|
2015-09-11 15:04:16 +00:00
|
|
|
side |
|
|
|
|
odd/spot |
|
2016-03-07 00:10:26 +00:00
|
|
|
annotated-tag |
|
|
|
|
doubly-annotated-tag |
|
2016-03-07 00:10:25 +00:00
|
|
|
doubly-signed-tag |
|
2015-09-11 15:04:16 +00:00
|
|
|
four |
|
|
|
|
one |
|
|
|
|
signed-tag |
|
|
|
|
three |
|
|
|
|
two |
|
|
|
|
EOF
|
|
|
|
git for-each-ref --format="%(refname:short) |%(contents:lines=0)" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'check `%(contents:lines=99999)`' '
|
2016-05-09 16:49:00 +00:00
|
|
|
cat >expect <<-\EOF &&
|
2020-12-17 01:07:08 +00:00
|
|
|
main |three
|
2015-09-11 15:04:16 +00:00
|
|
|
side |four
|
|
|
|
odd/spot |three
|
2016-03-07 00:10:26 +00:00
|
|
|
annotated-tag |An annotated tag
|
|
|
|
doubly-annotated-tag |Annonated doubly
|
2016-03-07 00:10:25 +00:00
|
|
|
doubly-signed-tag |Signed doubly
|
2015-09-11 15:04:16 +00:00
|
|
|
four |four
|
|
|
|
one |one
|
2016-03-07 00:10:25 +00:00
|
|
|
signed-tag |A signed tag
|
2015-09-11 15:04:16 +00:00
|
|
|
three |three
|
|
|
|
two |two
|
|
|
|
EOF
|
|
|
|
git for-each-ref --format="%(refname:short) |%(contents:lines=99999)" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '`%(contents:lines=-1)` should fail' '
|
|
|
|
test_must_fail git for-each-ref --format="%(refname:short) |%(contents:lines=-1)"
|
|
|
|
'
|
|
|
|
|
2015-09-10 15:48:25 +00:00
|
|
|
test_expect_success 'setup for version sort' '
|
|
|
|
test_commit foo1.3 &&
|
|
|
|
test_commit foo1.6 &&
|
|
|
|
test_commit foo1.10
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'version sort' '
|
|
|
|
git for-each-ref --sort=version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
foo1.3
|
|
|
|
foo1.6
|
|
|
|
foo1.10
|
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'version sort (shortened)' '
|
|
|
|
git for-each-ref --sort=v:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
foo1.3
|
|
|
|
foo1.6
|
|
|
|
foo1.10
|
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'reverse version sort' '
|
|
|
|
git for-each-ref --sort=-version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
foo1.10
|
|
|
|
foo1.6
|
|
|
|
foo1.3
|
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2017-01-10 08:49:34 +00:00
|
|
|
test_expect_success 'improper usage of %(if), %(then), %(else) and %(end) atoms' '
|
|
|
|
test_must_fail git for-each-ref --format="%(if)" &&
|
|
|
|
test_must_fail git for-each-ref --format="%(then) %(end)" &&
|
|
|
|
test_must_fail git for-each-ref --format="%(else) %(end)" &&
|
|
|
|
test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
|
|
|
|
test_must_fail git for-each-ref --format="%(if) %(then) %(then) %(end)" &&
|
|
|
|
test_must_fail git for-each-ref --format="%(then) %(else) %(end)" &&
|
|
|
|
test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
|
|
|
|
test_must_fail git for-each-ref --format="%(if) %(then) %(else)" &&
|
|
|
|
test_must_fail git for-each-ref --format="%(if) %(else) %(then) %(end)" &&
|
|
|
|
test_must_fail git for-each-ref --format="%(if) %(then) %(else) %(else) %(end)" &&
|
|
|
|
test_must_fail git for-each-ref --format="%(if) %(end)"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'check %(if)...%(then)...%(end) atoms' '
|
|
|
|
git for-each-ref --format="%(refname)%(if)%(authorname)%(then) Author: %(authorname)%(end)" >actual &&
|
|
|
|
cat >expect <<-\EOF &&
|
2020-12-17 01:07:08 +00:00
|
|
|
refs/heads/main Author: A U Thor
|
2017-01-10 08:49:34 +00:00
|
|
|
refs/heads/side Author: A U Thor
|
|
|
|
refs/odd/spot Author: A U Thor
|
|
|
|
refs/tags/annotated-tag
|
|
|
|
refs/tags/doubly-annotated-tag
|
|
|
|
refs/tags/doubly-signed-tag
|
|
|
|
refs/tags/foo1.10 Author: A U Thor
|
|
|
|
refs/tags/foo1.3 Author: A U Thor
|
|
|
|
refs/tags/foo1.6 Author: A U Thor
|
|
|
|
refs/tags/four Author: A U Thor
|
|
|
|
refs/tags/one Author: A U Thor
|
|
|
|
refs/tags/signed-tag
|
|
|
|
refs/tags/three Author: A U Thor
|
|
|
|
refs/tags/two Author: A U Thor
|
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'check %(if)...%(then)...%(else)...%(end) atoms' '
|
|
|
|
git for-each-ref --format="%(if)%(authorname)%(then)%(authorname)%(else)No author%(end): %(refname)" >actual &&
|
|
|
|
cat >expect <<-\EOF &&
|
2020-12-17 01:07:08 +00:00
|
|
|
A U Thor: refs/heads/main
|
2017-01-10 08:49:34 +00:00
|
|
|
A U Thor: refs/heads/side
|
|
|
|
A U Thor: refs/odd/spot
|
|
|
|
No author: refs/tags/annotated-tag
|
|
|
|
No author: refs/tags/doubly-annotated-tag
|
|
|
|
No author: refs/tags/doubly-signed-tag
|
|
|
|
A U Thor: refs/tags/foo1.10
|
|
|
|
A U Thor: refs/tags/foo1.3
|
|
|
|
A U Thor: refs/tags/foo1.6
|
|
|
|
A U Thor: refs/tags/four
|
|
|
|
A U Thor: refs/tags/one
|
|
|
|
No author: refs/tags/signed-tag
|
|
|
|
A U Thor: refs/tags/three
|
|
|
|
A U Thor: refs/tags/two
|
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
test_expect_success 'ignore spaces in %(if) atom usage' '
|
|
|
|
git for-each-ref --format="%(refname:short): %(if)%(HEAD)%(then)Head ref%(else)Not Head ref%(end)" >actual &&
|
|
|
|
cat >expect <<-\EOF &&
|
2020-12-17 01:07:08 +00:00
|
|
|
main: Head ref
|
2017-01-10 08:49:34 +00:00
|
|
|
side: Not Head ref
|
|
|
|
odd/spot: Not Head ref
|
|
|
|
annotated-tag: Not Head ref
|
|
|
|
doubly-annotated-tag: Not Head ref
|
|
|
|
doubly-signed-tag: Not Head ref
|
|
|
|
foo1.10: Not Head ref
|
|
|
|
foo1.3: Not Head ref
|
|
|
|
foo1.6: Not Head ref
|
|
|
|
four: Not Head ref
|
|
|
|
one: Not Head ref
|
|
|
|
signed-tag: Not Head ref
|
|
|
|
three: Not Head ref
|
|
|
|
two: Not Head ref
|
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2017-01-10 08:49:36 +00:00
|
|
|
test_expect_success 'check %(if:equals=<string>)' '
|
2020-12-17 01:07:08 +00:00
|
|
|
git for-each-ref --format="%(if:equals=main)%(refname:short)%(then)Found main%(else)Not main%(end)" refs/heads/ >actual &&
|
2017-01-10 08:49:36 +00:00
|
|
|
cat >expect <<-\EOF &&
|
2020-12-17 01:07:08 +00:00
|
|
|
Found main
|
|
|
|
Not main
|
2017-01-10 08:49:36 +00:00
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'check %(if:notequals=<string>)' '
|
2020-12-17 01:07:08 +00:00
|
|
|
git for-each-ref --format="%(if:notequals=main)%(refname:short)%(then)Not main%(else)Found main%(end)" refs/heads/ >actual &&
|
2017-01-10 08:49:36 +00:00
|
|
|
cat >expect <<-\EOF &&
|
2020-12-17 01:07:08 +00:00
|
|
|
Found main
|
|
|
|
Not main
|
2017-01-10 08:49:36 +00:00
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2020-09-16 02:08:40 +00:00
|
|
|
test_expect_success '--merged is compatible with --no-merged' '
|
|
|
|
git for-each-ref --merged HEAD --no-merged HEAD
|
2017-03-21 12:58:49 +00:00
|
|
|
'
|
|
|
|
|
2019-04-29 05:19:42 +00:00
|
|
|
test_expect_success 'validate worktree atom' '
|
|
|
|
cat >expect <<-EOF &&
|
2020-12-17 01:07:08 +00:00
|
|
|
main: $(pwd)
|
|
|
|
main_worktree: $(pwd)/worktree_dir
|
2019-04-29 05:19:42 +00:00
|
|
|
side: not checked out
|
|
|
|
EOF
|
2020-12-17 01:07:08 +00:00
|
|
|
git worktree add -b main_worktree worktree_dir main &&
|
2019-04-29 05:19:42 +00:00
|
|
|
git for-each-ref --format="%(refname:short): %(if)%(worktreepath)%(then)%(worktreepath)%(else)not checked out%(end)" refs/heads/ >actual &&
|
|
|
|
rm -r worktree_dir &&
|
|
|
|
git worktree prune &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2015-07-09 06:03:21 +00:00
|
|
|
test_done
|