mbox series

[v2,0/4] forbid HEAD as a tagname

Message ID 20241203023240.3852850-1-gitster@pobox.com (mailing list archive)
Headers show
Series forbid HEAD as a tagname | expand

Message

Junio C Hamano Dec. 3, 2024, 2:32 a.m. UTC
As discussed earlier, if you accidentally did "git tag HEAD",
the command happily creates a tag with HEAD as its name, but then it
would be confusing as use of it becomes ambiguous with the most often
used ref, HEAD, the currently checked-out commit.

Let's forbid creation of such a tag using the "git tag" Porcelain
command, while still allowing creation of such a ref using the
plumbing command "git update-ref".  "git tag -d HEAD" can still be
used to remove such a tag to recover from an earlier mistake.  This
follows the design pattern used to forbid use of "HEAD" as a branch
name, where "git branch" refuses to create such a branch, but "git
update-ref" is usable to do so.

The intent is that the repository layout and format allows use of
such names and we keep our low-level command usable for those who
want to write a different UI with different usability constrants
(e.g. they may not even have a concept of "currently checked-out
branch" hence the word HEAD may not even be special).

The first two clean-up patches are unchanged.

The third step has an updated log message to mention an unrelated
clean-up of the test.

The final step has an extra test to make sure that "update-ref" is
still usable to create such a tag, and "git tag -d" can remove it.

Junio C Hamano (4):
  refs: move ref name helpers around
  refs: drop strbuf_ prefix from helpers
  t5604: do not expect that HEAD can be a valid tagname
  tag: "git tag" refuses to use HEAD as a tagname

 branch.c                   |  2 +-
 builtin/branch.c           | 10 ++++----
 builtin/check-ref-format.c |  2 +-
 builtin/checkout.c         |  2 +-
 builtin/merge.c            |  2 +-
 builtin/tag.c              | 13 +----------
 builtin/worktree.c         |  8 +++----
 gitweb/gitweb.perl         |  2 +-
 object-name.c              | 36 -----------------------------
 refs.c                     | 47 ++++++++++++++++++++++++++++++++++++++
 refs.h                     | 29 +++++++++++++++++++++++
 strbuf.h                   | 22 ------------------
 t/t5604-clone-reference.sh |  6 ++---
 t/t7004-tag.sh             | 12 ++++++++++
 14 files changed, 106 insertions(+), 87 deletions(-)

1:  717418e6c0 = 1:  717418e6c0 refs: move ref name helpers around
2:  e7b29c0967 = 2:  e7b29c0967 refs: drop strbuf_ prefix from helpers
3:  e143e68d9c ! 3:  a0efd9b681 t5604: do not expect that HEAD is a valid tagname
    @@ Metadata
     Author: Junio C Hamano <gitster@pobox.com>
     
      ## Commit message ##
    -    t5604: do not expect that HEAD is a valid tagname
    +    t5604: do not expect that HEAD can be a valid tagname
     
         09116a1c (refs: loosen over-strict "format" check, 2011-11-16)
         introduced a test piece (originally in t5700) that expects to be
    @@ Commit message
         Before forbidding "git tag" from creating "refs/tags/HEAD", update
         these tests to use 'foo', not 'HEAD', as the name of the test tag.
     
    +    Note that the test piece that uses the tag learned the value of the
    +    tag in unnecessarily inefficient and convoluted way with for-each-ref.
    +    Just use "rev-parse" instead.
    +
         Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      ## t/t5604-clone-reference.sh ##
4:  6595acfbf3 ! 4:  2c6438eccf tag: "git tag" refuses to use HEAD as a tagname
    @@ Commit message
         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>
     
      ## refs.c ##
    @@ t/t7004-tag.sh: test_expect_success 'creating a tag using default HEAD should su
      '
      
     +test_expect_success 'HEAD is forbidden as a tagname' '
    -+	test_when_finished "git tag -d HEAD || :" &&
    ++	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 \