Which characters are illegal within a branch name?
Which characters are illegal within a branch name?
Naming rules for refname:
Git imposes the following rules on how references are named:
They can include slash
/
for hierarchical (directory) grouping, but no slash-separated component can begin with a dot.
or end with the sequence.lock
.They must contain at least one
/
. This enforces the presence of a category likeheads/
,tags/
etc. but the actual names are not restricted. If the--allow-onelevel
option is used, this rule is waived.They cannot have two consecutive dots
..
anywhere.They cannot have ASCII control characters (i.e. bytes whose values are lower than
\040
, or\177
DEL
), space, tilde~
, caret^
, or colon:
anywhere.They cannot have question-mark
?
, asterisk*
, or open bracket[
anywhere. See the--refspec-pattern
option below for an exception to this rule.They cannot begin or end with a slash
/
or contain multiple consecutive slashes (see the--normalize
option below for an exception to this rule)They cannot end with a dot
.
They cannot contain a sequence
@{
.They cannot be the single character
@
.They cannot contain a
\
.
On top of that, additional rule for branch name:
- They cannot start with a dash
-
Thanks to Jakub Narębski, the man page for git check-ref-format
has more details.
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 'Ω'