tag: "git tag" refuses to use HEAD as a tagname

Even though the plumbing level allows you to create refs/tags/HEAD
and refs/heads/HEAD, doing so makes it confusing within the context
of the UI Git Porcelain commands provides.  Just like we prevent a
branch from getting called "HEAD" at the Porcelain layer (i.e. "git
branch" command), teach "git tag" to refuse to create a tag "HEAD".

With a few new tests, we make sure that

 - "git tag HEAD" and "git tag -a HEAD" are rejected

 - "git update-ref refs/tags/HEAD" is still allowed (this is a
   deliberate design decision to allow others to create their own UI
   on top of Git infrastructure that may be different from our UI).

 - "git tag -d HEAD" can remove refs/tags/HEAD to recover from an
   mistake.

Helped-by: Jeff King <peff@peff.net>
Helped-by: Rubén Justo <rjusto@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Junio C Hamano 2024-12-03 11:32:40 +09:00
parent e5ce5b05d0
commit bbd445d5ef
2 changed files with 13 additions and 1 deletions

2
refs.c
View File

@ -735,7 +735,7 @@ int check_branch_ref(struct strbuf *sb, const char *name)

int check_tag_ref(struct strbuf *sb, const char *name)
{
if (name[0] == '-')
if (name[0] == '-' || !strcmp(name, "HEAD"))
return -1;

strbuf_reset(sb);

View File

@ -91,6 +91,18 @@ test_expect_success 'creating a tag using default HEAD should succeed' '
test_must_fail git reflog exists refs/tags/mytag
'

test_expect_success 'HEAD is forbidden as a tagname' '
test_when_finished "git update-ref --no-deref -d refs/tags/HEAD || :" &&
test_must_fail git tag HEAD &&
test_must_fail git tag -a -m "useless" HEAD
'

test_expect_success '"git tag" can remove a tag named HEAD' '
test_when_finished "git update-ref --no-deref -d refs/tags/HEAD || :" &&
git update-ref refs/tags/HEAD HEAD &&
git tag -d HEAD
'

test_expect_success 'creating a tag with --create-reflog should create reflog' '
git log -1 \
--format="format:tag: tagging %h (%s, %cd)%n" \