Which characters are illegal within a branch name?
GitBranchNamingGit Problem Overview
Which characters are illegal within a branch name?
Git Solutions
Solution 1 - Git
Naming rules for refname:
> Git imposes the following rules on how references are named:
>
> 1. They can include slash /
for hierarchical (directory) grouping, but no slash-separated component can begin with a dot .
or end with the sequence .lock
.
>
> 2. They must contain at least one /
. This enforces the presence of a category like heads/
, tags/
etc. but the actual names are not restricted. If the --allow-onelevel
option is used, this rule is waived.
>
> 3. They cannot have two consecutive dots ..
anywhere.
>
> 4. They cannot have ASCII control characters (i.e. bytes whose values are lower than \040
, or \177
DEL
), space, tilde ~
, caret ^
, or colon :
anywhere.
>
> 5. They cannot have question-mark ?
, asterisk *
, or open bracket [
anywhere. See the --refspec-pattern
option below for an exception to this rule.
>
> 6. They cannot begin or end with a slash /
or contain multiple consecutive slashes (see the --normalize
option below for an exception to this rule)
>
> 7. They cannot end with a dot .
>
> 8. They cannot contain a sequence @{
.
>
> 9. They cannot be the single character @
.
>
> 10. They cannot contain a \
.
On top of that, additional rule for branch name:
> 1. They cannot start with a dash -
Thanks to Jakub Narębski, the man page for git check-ref-format
has more details.
Solution 2 - Git
The accepted answer and the man page already explain which rules apply to Git branch names.
In the Git source code, the refname_disposition array is used to determine how to handle various characters in refnames
.
The indexes in the array correspond to ASCII codes and the values indicate how the ASCII characters are handled.
/*
* How to handle various characters in refnames:
* 0: An acceptable character for refs
* 1: End-of-component
* 2: ., look for a preceding . to reject .. in refs
* 3: {, look for a preceding @ to reject @{ in refs
* 4: A bad character: ASCII control characters, and
* ":", "?", "[", "\", "^", "~", SP, or TAB
* 5: *, reject unless REFNAME_REFSPEC_PATTERN is set
*/
static unsigned char refname_disposition[256] = {
1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4
};
Since 4
means that the corresponding ASCII character is not allowed inside branch names, there are 39 disallowed characters.
The disallowed characters are ASCII control characters (ASCII codes < 32), the printable characters : ? [ \ ^ ~
and the whitespace/tab character.
3 more characters require some conditions to be met (see doc comment):
.
: Two subsequent dots are forbidden.{
: The substring@{
is forbidden.*
: Reject unlessREFNAME_REFSPEC_PATTERN
is set.
The null byte terminates the branch name and /
creates a new directory hierarchy for the branch.
Therefore, branch names cannot end with a slash.
For example git checkout -b 'a/b/c'
will create the corresponding directory structure under .git/refs/heads
Note that UTF-8
characters can be used in branch names:
$ git checkout -b $'\xCE\xA9'
Switched to a new branch 'Ω'
Solution 3 - Git
As an addition, care must be taken if you consider to use the dollar sign $
character.
git branch pew$ign
will create pew. In order to create a branch that has $
within it the whole name should be wrapped in quotes: git branch 'pewSign'
. Ideally you should avoid to use the symbol whatsoever.
Solution 4 - Git
It doesn't like > or ==> or ->
Solution 5 - Git
To complete the main answer by Manoj Govindan :
@
is a valid branch name (on git versiongit version 2.24.3 (Apple Git-128)
)HEAD
is not a valid branch name (by captain obvious!)- length is limited (by the OS, on Mac OS 10.15.7, 250 characters is the maximum, either ascii or not-ascii)