分支名称中哪些字符是非法的?


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 like heads/, 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 \.

在此之上,分支名称的附加规则:

他们不能以破折号开头

感谢Jakub narabbski, git check-ref-format的手册页提供了更多细节。


另外,如果考虑使用美元符号$字符,则必须小心。

Git分支pew$ign将创建pew。

为了创建一个包含$的分支,整个名称应该用引号括起来,使其成为字符串字面量:git branch 'pew$ign'。理想情况下,你应该避免使用任何符号。


接受的答案和手册页已经解释了哪些规则适用于Git分支名称。

在Git源代码中,refname_disposition数组用于确定如何处理refname中的各种字符。 数组中的索引对应于ASCII码,值表示如何处理ASCII字符。

/*
 * 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
};

因为4意味着分支名称中不允许使用相应的ASCII字符,所以不允许使用39个字符。 不允许的字符是ASCII控制字符(ASCII码< 32),可打印字符:?[\ ^ ~和空格/制表符。

3个字符需要满足一些条件(见文档注释):

:禁止两个后续点。 {:禁止使用子字符串@{。 *:拒绝,除非REFNAME_REFSPEC_PATTERN被设置。

空字节终止分支名称和/为分支创建一个新的目录层次结构。 因此,分支名称不能以斜杠结尾。 例如,git checkout -b 'a/b/c'将在.git/refs/heads下创建相应的目录结构

注意,分支名称可以使用UTF-8字符:

$ git checkout -b $'\xCE\xA9'
Switched to a new branch 'Ω'

它不像>或==>或->


Manoj Govindan的主要回答是:

@是有效的分支名称(在git版本git version 2.24.3 (Apple git -128)上) HEAD不是有效的分支名称(显然是由船长指定的!) 长度是有限的(由操作系统,在Mac OS 10.15.7, 250个字符是最大的,无论是ascii或非ascii)