Volume XXII, number 279Tuesday, October 6, 2026Latest message 43 minutes ago

The Git List

News and archive of git@vger.kernel.org, since April 2005

[Bug] Porcelain allows creation of '@' branch

8 messages between Aug 31, 2026 and Sep 6, 2026, from Bence Csókás, D. Ben Knoble, Jeff King, Kristoffer Haugsbakk, Ben Knoble, Junio C Hamano.

Plain Markdown or JSON for tools and agents.

Bence CsókásAug 31, 2026, 14:22 UTC on lore
Hi,

I ran into this issue a few weeks ago. I'm using Git 2.55.0, which is the latest released.

`git help check-ref-format` says this about a branch name:
   [...]
   9. They cannot be the single character @.
   [...]
And as expected, it is rejected:
   $ git check-ref-format @ && echo BUG!
   $
However, the following commands all create a branch named @ :
   $ git checkout -b @
   $ git switch -c @
   $ git branch @

I believe this to be a bug. Other invalid names are properly rejected though:

   $ git checkout -b master@{1}
   fatal: 'master@{1}' is not a valid branch name
   hint: See 'git help check-ref-format'
   hint: Disable this message with "git config set advice.refSyntax false"
   $ git checkout -b @{1}
   fatal: '@{1}' is not a valid branch name
   hint: See 'git help check-ref-format'
   hint: Disable this message with "git config set advice.refSyntax false"
   $ git checkout -b @^
   fatal: '@^' is not a valid branch name
   hint: See 'git help check-ref-format'
   hint: Disable this message with "git config set advice.refSyntax false"

After creation, this branch cannot be checked out again, as `git checkout @` is a no-op. Luckily though, `git branch -d @` works, so I didn't permanently damage my Git repo :P

Bence

P.S. as I was typing this mail, I realized that I should've given `--branch` to check-ref-format, and sure enough, there's the problem:

   $ git check-ref-format --branch @
   @
   $ git check-ref-format --branch @{1}
   fatal: '@{1}' is not a valid branch name
   $

Not sure why it thinks that would be a valid branch name... IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

D. Ben KnobleAug 31, 2026, 19:59 UTC in reply to Bence Csókás on lore

Re: [Bug] Porcelain allows creation of '@' branch

On Mon, Aug 31, 2026 at 3:12 PM Bence Csókás <bence.csokas@arm.com> wrote:
Show 11 quoted lines
>
> Hi,
>
> I ran into this issue a few weeks ago. I'm using Git 2.55.0, which is
> the latest released.
>
> `git help check-ref-format` says this about a branch name:
>
>    [...]
>    9. They cannot be the single character @.
>    [...]
This is the rule for a reference.
Show 10 quoted lines
> And as expected, it is rejected:
>
>    $ git check-ref-format @ && echo BUG!
>    $
>
> However, the following commands all create a branch named @ :
>
>    $ git checkout -b @
>    $ git switch -c @
>    $ git branch @
But (with git refs list) we should see this creates a ref "refs/heads/@".

I happen to think that's extremely confusing given that "@" is the shorthand for HEAD, but… it's not against the current documented rules, I think. (e.g., "git switch @" will fail, since it sees "git switch HEAD"; using "refs/heads/@" will also fail.) git-checkout doesn't fail but also doesn't change to the "@" branch. Futzing with .git/HEAD and restoring the working tree works, but… yikes.

Of course, --branch mode is allowed to be stricter; maybe we should reject this case?

Show 33 quoted lines
> I believe this to be a bug. Other invalid names are properly rejected
> though:
>
>    $ git checkout -b master@{1}
>    fatal: 'master@{1}' is not a valid branch name
>    hint: See 'git help check-ref-format'
>    hint: Disable this message with "git config set advice.refSyntax false"
>    $ git checkout -b @{1}
>    fatal: '@{1}' is not a valid branch name
>    hint: See 'git help check-ref-format'
>    hint: Disable this message with "git config set advice.refSyntax false"
>    $ git checkout -b @^
>    fatal: '@^' is not a valid branch name
>    hint: See 'git help check-ref-format'
>    hint: Disable this message with "git config set advice.refSyntax false"
>
> After creation, this branch cannot be checked out again, as `git
> checkout @` is a no-op. Luckily though, `git branch -d @` works, so I
> didn't permanently damage my Git repo :P
>
> Bence
>
> P.S. as I was typing this mail, I realized that I should've given
> `--branch` to check-ref-format, and sure enough, there's the problem:
>
>    $ git check-ref-format --branch @
>    @
>    $ git check-ref-format --branch @{1}
>    fatal: '@{1}' is not a valid branch name
>    $
>
> Not sure why it thinks that would be a valid branch name...
> IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
(I don't recall offhand where we describe valid branch names, if at all.)
-- 
D. Ben Knoble
Jeff KingSep 2, 2026, 07:37 UTC in reply to D. Ben Knoble on lore

Re: [Bug] Porcelain allows creation of '@' branch

On Mon, Aug 31, 2026 at 03:59:56PM -0400, D. Ben Knoble wrote:
Show 11 quoted lines
> But (with git refs list) we should see this creates a ref "refs/heads/@".
> 
> I happen to think that's extremely confusing given that "@" is the
> shorthand for HEAD, but… it's not against the current documented
> rules, I think. (e.g., "git switch @" will fail, since it sees "git
> switch HEAD"; using "refs/heads/@" will also fail.) git-checkout
> doesn't fail but also doesn't change to the "@" branch. Futzing with
> .git/HEAD and restoring the working tree works, but… yikes.
> 
> Of course, --branch mode is allowed to be stricter; maybe we should
> reject this case?

Yeah, sadly bare "@" is allowed in a component (but not "@{") because we've maintained strict backwards compatibility. So I don't think it's a _bug_ exactly, but in the past we have restricted the porcelain interfaces (so git-branch, but not git-update-ref) to avoid such footguns. The most notable one is HEAD:

  $ git check-ref-format refs/heads/HEAD; echo $?
  0
  $ git check-ref-format --branch HEAD; echo $?
  fatal: 'HEAD' is not a valid branch name
  128

which also shows off that "--branch" is a convenience option for using those stricter porcelain rules.

I think it would make sense to treat bare "@" the same as HEAD here. We probably _don't_ want to forbid any "@", though. Branches and tags like foo@bar are legal (if IMHO somewhat gross), and less likely to be used accidentally.

So I think there is no bug, in the sense that the system is working as designed, but it sure would be a nice feature to block this footgun.

> (I don't recall offhand where we describe valid branch names, if at all.)

I don't think we document the magic porcelain-tightening rules anywhere. That's probably OK in practice; the point of "check-ref-format --branch" is to check against them programatically.

-Peff
Kristoffer HaugsbakkSep 3, 2026, 08:38 UTC in reply to D. Ben Knoble on lore

Re: [Bug] Porcelain allows creation of '@' branch

On Mon, Aug 31, 2026, at 21:59, D. Ben Knoble wrote:
Show 37 quoted lines
> On Mon, Aug 31, 2026 at 3:12 PM Bence Csókás <bence.csokas@arm.com> wrote:
>>
>> Hi,
>>
>> I ran into this issue a few weeks ago. I'm using Git 2.55.0, which is
>> the latest released.
>>
>> `git help check-ref-format` says this about a branch name:
>>
>>    [...]
>>    9. They cannot be the single character @.
>>    [...]
>
> This is the rule for a reference.
>
>> And as expected, it is rejected:
>>
>>    $ git check-ref-format @ && echo BUG!
>>    $
>>
>> However, the following commands all create a branch named @ :
>>
>>    $ git checkout -b @
>>    $ git switch -c @
>>    $ git branch @
>
> But (with git refs list) we should see this creates a ref "refs/heads/@".
>
> I happen to think that's extremely confusing given that "@" is the
> shorthand for HEAD, but… it's not against the current documented
> rules, I think. (e.g., "git switch @" will fail, since it sees "git
> switch HEAD"; using "refs/heads/@" will also fail.) git-checkout
> doesn't fail but also doesn't change to the "@" branch. Futzing with
> .git/HEAD and restoring the working tree works, but… yikes.
>
> Of course, --branch mode is allowed to be stricter; maybe we should
> reject this case?
Not a bug (2024) https://lore.kernel.org/git/xmqqy12z7eti.fsf@gitster.g/
    I suspect that it is much more productive to deprecate and remove
    "@" that is a built-in synomym for HEAD (but "refs/remotes/origin/@"
    does not act as a synonym for "refs/remotes/origin/HEAD"). [...]
>[snip]
Bence CsókásSep 3, 2026, 12:35 UTC in reply to Kristoffer Haugsbakk on lore

Re: [Bug] Porcelain allows creation of '@' branch

On 2026. 09. 03. 10:38, Kristoffer Haugsbakk wrote:
Show 5 quoted lines
> Not a bug (2024) https://lore.kernel.org/git/xmqqy12z7eti.fsf@gitster.g/
>
>      I suspect that it is much more productive to deprecate and remove
>      "@" that is a built-in synomym for HEAD (but "refs/remotes/origin/@"
>      does not act as a synonym for "refs/remotes/origin/HEAD"). [...]

I would not want to see @ removed, I have abandoned using HEAD years ago, too much typing (especially if you want to express more complex things, e.g. `git range-diff long-branch-name{^..otherbranch,..@}`, to pick an example out of my bash-history).

Bence IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

Ben KnobleSep 3, 2026, 15:14 UTC in reply to Bence Csókás on lore

Re: [Bug] Porcelain allows creation of '@' branch

Show 12 quoted lines
> Le 3 sept. 2026 à 08:36, Bence Csókás <bence.csokas@arm.com> a écrit :
> 
> On 2026. 09. 03. 10:38, Kristoffer Haugsbakk wrote:
>> Not a bug (2024) https://lore.kernel.org/git/xmqqy12z7eti.fsf@gitster.g/
>> 
>>     I suspect that it is much more productive to deprecate and remove
>>     "@" that is a built-in synomym for HEAD (but "refs/remotes/origin/@"
>>     does not act as a synonym for "refs/remotes/origin/HEAD"). [...]
> I would not want to see @ removed, I have abandoned using HEAD years
> ago, too much typing (especially if you want to express more complex
> things, e.g. `git range-diff long-branch-name{^..otherbranch,..@}`, to
> pick an example out of my bash-history).
Ditto, though thanks for digging up the reference. It will surely be important to justify when proposing to tighten the branch-mode rules. 
Junio C HamanoSep 3, 2026, 18:45 UTC in reply to Ben Knoble on lore

Re: [Bug] Porcelain allows creation of '@' branch

Ben Knoble <ben.knoble@gmail.com> writes:
Show 14 quoted lines
>> Le 3 sept. 2026 à 08:36, Bence Csókás <bence.csokas@arm.com> a écrit :
>> 
>> On 2026. 09. 03. 10:38, Kristoffer Haugsbakk wrote:
>>> Not a bug (2024) https://lore.kernel.org/git/xmqqy12z7eti.fsf@gitster.g/
>>> 
>>>     I suspect that it is much more productive to deprecate and remove
>>>     "@" that is a built-in synomym for HEAD (but "refs/remotes/origin/@"
>>>     does not act as a synonym for "refs/remotes/origin/HEAD"). [...]
>> I would not want to see @ removed, I have abandoned using HEAD years
>> ago, too much typing (especially if you want to express more complex
>> things, e.g. `git range-diff long-branch-name{^..otherbranch,..@}`, to
>> pick an example out of my bash-history).
>
> Ditto, though thanks for digging up the reference. It will surely be important to justify when proposing to tighten the branch-mode rules. 

It is very unfortunate that the quote is partial and incomplete, though, and would not be a good input for people to decide on their own.

Kristoffer HaugsbakkSep 6, 2026, 07:56 UTC in reply to Junio C Hamano on lore

Re: [Bug] Porcelain allows creation of '@' branch

On Thu, Sep 3, 2026, at 20:45, Junio C Hamano wrote:
Show 20 quoted lines
> Ben Knoble <ben.knoble@gmail.com> writes:
>
>>> Le 3 sept. 2026 à 08:36, Bence Csókás <bence.csokas@arm.com> a écrit :
>>>
>>> On 2026. 09. 03. 10:38, Kristoffer Haugsbakk wrote:
>>>> Not a bug (2024) https://lore.kernel.org/git/xmqqy12z7eti.fsf@gitster.g/
>>>>
>>>>     I suspect that it is much more productive to deprecate and remove
>>>>     "@" that is a built-in synomym for HEAD (but "refs/remotes/origin/@"
>>>>     does not act as a synonym for "refs/remotes/origin/HEAD"). [...]
>>> I would not want to see @ removed, I have abandoned using HEAD years
>>> ago, too much typing (especially if you want to express more complex
>>> things, e.g. `git range-diff long-branch-name{^..otherbranch,..@}`, to
>>> pick an example out of my bash-history).
>>
>> Ditto, though thanks for digging up the reference. It will surely be important to justify when proposing to tighten the branch-mode rules.
>
> It is very unfortunate that the quote is partial and incomplete,
> though, and would not be a good input for people to decide on their
> own.

Sorry that I misrepresented your post. The gist to me was that you weren’t interested in more code to deal with the `@` shorthand.

Back to recent threads