Skip to content

Commit 6a33814

Browse files
avargitster
authored andcommitted
tag: implicitly supply --list given another list-like option
Change the "tag" command to implicitly turn on its --list mode when provided with a list-like option such as --contains, --points-at etc. This is for consistency with how "branch" works. When "branch" is given a list-like option, such as --contains, it implicitly provides --list. Before this change "tag" would error out on those sorts of invocations. I.e. while both of these worked for "branch": git branch --contains v2.8.0 <pattern> git branch --list --contains v2.8.0 <pattern> Only the latter form worked for "tag": git tag --contains v2.8.0 '*rc*' git tag --list --contains v2.8.0 '*rc*' Now "tag", like "branch", will implicitly supply --list when a list-like option is provided, and no other conflicting non-list options (such as -d) are present on the command-line. Spelunking through the history via: git log --reverse -p -G'only allowed with' -- '*builtin*tag*c' Reveals that there was no good reason for not allowing this in the first place. The --contains option added in 32c35cf ("git-tag: Add --contains option", 2009-01-26) made this an error. All the other subsequent list-like options that were added copied its pattern of making this usage an error. The only tests that break as a result of this change are tests that were explicitly checking that this "branch-like" usage wasn't permitted. Change those failing tests to check that this invocation mode is permitted, add extra tests for the list-like options we weren't testing, and tests to ensure that e.g. we don't toggle the list mode in the presence of other conflicting non-list options. With this change errors messages such as "--contains option is only allowed with -l" don't make sense anymore, since options like --contain turn on -l. Instead we error out when list-like options such as --contain are used in conjunction with conflicting options such as -d or -v. Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c485b24 commit 6a33814

File tree

3 files changed

+73
-17
lines changed

3 files changed

+73
-17
lines changed

Documentation/git-tag.txt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,11 @@ OPTIONS
8282

8383
-n<num>::
8484
<num> specifies how many lines from the annotation, if any,
85-
are printed when using -l.
86-
The default is not to print any annotation lines.
87-
If no number is given to `-n`, only the first line is printed.
88-
If the tag is not annotated, the commit message is displayed instead.
85+
are printed when using -l. Implies `--list`.
86+
+
87+
The default is not to print any annotation lines.
88+
If no number is given to `-n`, only the first line is printed.
89+
If the tag is not annotated, the commit message is displayed instead.
8990

9091
-l::
9192
--list::
@@ -95,6 +96,10 @@ OPTIONS
9596
Running "git tag" without arguments also lists all tags. The pattern
9697
is a shell wildcard (i.e., matched using fnmatch(3)). Multiple
9798
patterns may be given; if any of them matches, the tag is shown.
99+
+
100+
This option is implicitly supplied if any other list-like option such
101+
as `--contains` is provided. See the documentation for each of those
102+
options for details.
98103

99104
--sort=<key>::
100105
Sort based on the key given. Prefix `-` to sort in
@@ -123,7 +128,7 @@ This option is only applicable when listing tags without annotation lines.
123128

124129
--contains [<commit>]::
125130
Only list tags which contain the specified commit (HEAD if not
126-
specified).
131+
specified). Implies `--list`.
127132

128133
--merged [<commit>]::
129134
Only list tags whose commits are reachable from the specified
@@ -134,7 +139,7 @@ This option is only applicable when listing tags without annotation lines.
134139
commit (`HEAD` if not specified), incompatible with `--merged`.
135140

136141
--points-at <object>::
137-
Only list tags of the given object.
142+
Only list tags of the given object. Implies `--list`.
138143

139144
-m <msg>::
140145
--message=<msg>::

builtin/tag.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -454,8 +454,14 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
454454
}
455455
create_tag_object = (opt.sign || annotate || msg.given || msgfile);
456456

457-
if (argc == 0 && !cmdmode)
458-
cmdmode = 'l';
457+
if (!cmdmode) {
458+
if (argc == 0)
459+
cmdmode = 'l';
460+
else if (filter.with_commit ||
461+
filter.points_at.nr || filter.merge_commit ||
462+
filter.lines != -1)
463+
cmdmode = 'l';
464+
}
459465

460466
if ((create_tag_object || force) && (cmdmode != 0))
461467
usage_with_options(git_tag_usage, options);
@@ -485,13 +491,13 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
485491
return ret;
486492
}
487493
if (filter.lines != -1)
488-
die(_("-n option is only allowed with -l."));
494+
die(_("-n option is only allowed in list mode"));
489495
if (filter.with_commit)
490-
die(_("--contains option is only allowed with -l."));
496+
die(_("--contains option is only allowed in list mode"));
491497
if (filter.points_at.nr)
492-
die(_("--points-at option is only allowed with -l."));
498+
die(_("--points-at option is only allowed in list mode"));
493499
if (filter.merge_commit)
494-
die(_("--merged and --no-merged option are only allowed with -l"));
500+
die(_("--merged and --no-merged options are only allowed in list mode"));
495501
if (cmdmode == 'd')
496502
return for_each_tag_name(argv, delete_tag, NULL);
497503
if (cmdmode == 'v') {

t/t7004-tag.sh

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,11 @@ test_expect_success \
643643
git tag -n0 -l tag-one-line >actual &&
644644
test_cmp expect actual &&
645645
646+
git tag -n0 | grep "^tag-one-line" >actual &&
647+
test_cmp expect actual &&
648+
git tag -n0 tag-one-line >actual &&
649+
test_cmp expect actual &&
650+
646651
echo "tag-one-line A msg" >expect &&
647652
git tag -n1 -l | grep "^tag-one-line" >actual &&
648653
test_cmp expect actual &&
@@ -656,6 +661,17 @@ test_expect_success \
656661
test_cmp expect actual
657662
'
658663

664+
test_expect_success 'The -n 100 invocation means -n --list 100, not -n100' '
665+
>expect &&
666+
git tag -n 100 >actual &&
667+
test_cmp expect actual &&
668+
669+
git tag -m "A msg" 100 &&
670+
echo "100 A msg" >expect &&
671+
git tag -n 100 >actual &&
672+
test_cmp expect actual
673+
'
674+
659675
test_expect_success \
660676
'listing the zero-lines message of a non-signed tag should succeed' '
661677
git tag -m "" tag-zero-lines &&
@@ -1476,6 +1492,11 @@ test_expect_success 'checking that initial commit is in all tags' "
14761492
test_cmp expected actual
14771493
"
14781494

1495+
test_expect_success 'checking that --contains can be used in non-list mode' '
1496+
git tag --contains $hash1 v* >actual &&
1497+
test_cmp expected actual
1498+
'
1499+
14791500
# mixing modes and options:
14801501

14811502
test_expect_success 'mixing incompatibles modes and options is forbidden' '
@@ -1496,7 +1517,6 @@ test_expect_success 'mixing incompatibles modes and options is forbidden' '
14961517
test_must_fail git tag -l -v &&
14971518
test_must_fail git tag -l -d &&
14981519
test_must_fail git tag -l -v -d &&
1499-
test_must_fail git tag -n 100 &&
15001520
test_must_fail git tag -n 100 -v &&
15011521
test_must_fail git tag -l -m msg &&
15021522
test_must_fail git tag -l -F some file &&
@@ -1505,10 +1525,25 @@ test_expect_success 'mixing incompatibles modes and options is forbidden' '
15051525
test_must_fail git tag --contains tag-blob
15061526
'
15071527

1528+
for option in --contains --merged --no-merged --points-at
1529+
do
1530+
test_expect_success "mixing incompatible modes with $option is forbidden" "
1531+
test_must_fail git tag -d $option HEAD &&
1532+
test_must_fail git tag -d $option HEAD some-tag &&
1533+
test_must_fail git tag -v $option HEAD
1534+
"
1535+
test_expect_success "Doing 'git tag --list-like $option <commit> <pattern> is permitted" "
1536+
git tag -n $option HEAD HEAD &&
1537+
git tag $option HEAD HEAD
1538+
"
1539+
done
1540+
15081541
# check points-at
15091542

1510-
test_expect_success '--points-at cannot be used in non-list mode' '
1511-
test_must_fail git tag --points-at=v4.0 foo
1543+
test_expect_success '--points-at can be used in non-list mode' '
1544+
echo v4.0 >expect &&
1545+
git tag --points-at=v4.0 "v*" >actual &&
1546+
test_cmp expect actual
15121547
'
15131548

15141549
test_expect_success '--points-at finds lightweight tags' '
@@ -1785,8 +1820,13 @@ test_expect_success 'setup --merged test tags' '
17851820
git tag mergetest-3 HEAD
17861821
'
17871822

1788-
test_expect_success '--merged cannot be used in non-list mode' '
1789-
test_must_fail git tag --merged=mergetest-2 foo
1823+
test_expect_success '--merged can be used in non-list mode' '
1824+
cat >expect <<-\EOF &&
1825+
mergetest-1
1826+
mergetest-2
1827+
EOF
1828+
git tag --merged=mergetest-2 "mergetest*" >actual &&
1829+
test_cmp expect actual
17901830
'
17911831

17921832
test_expect_success '--merged is incompatible with --no-merged' '
@@ -1810,6 +1850,11 @@ test_expect_success '--no-merged show unmerged tags' '
18101850
test_cmp expect actual
18111851
'
18121852

1853+
test_expect_success '--no-merged can be used in non-list mode' '
1854+
git tag --no-merged=mergetest-2 mergetest-* >actual &&
1855+
test_cmp expect actual
1856+
'
1857+
18131858
test_expect_success 'ambiguous branch/tags not marked' '
18141859
git tag ambiguous &&
18151860
git branch ambiguous &&

0 commit comments

Comments
 (0)