【问题标题】:GIT: How to unambiguously reference current HEAD when having a branch called HEAD?GIT:当有一个名为 HEAD 的分支时,如何明确引用当前的 HEAD?
【发布时间】:2025-12-16 10:05:01
【问题描述】:

尽管“HEAD”对于 Git 分支的名称来说绝对是一个糟糕的选择,但它仍然是一个有效的分支名称。如果您碰巧有名为“HEAD”的分支,有没有办法明确引用实际的HEAD 符号引用?

分支可以引用为refs/heads/HEAD,但HEAD本身呢?

<commit> 作为参数传递的任何地方,仅使用 HEAD 会导致 refname 'HEAD' is ambiguous 错误。

【问题讨论】:

  • 可怕,可怕的做法。但好问题:)。对于那里的读者,如果您想知道是否应该将分支命名为 HEAD,请不要。
  • 我认为在各处重命名此分支比解决此问题花费更少的精力,但以后会遇到更多麻烦...
  • @MadaraUchiha 使用 Git 2.16(2018 年第一季度),您将无法将分支命名为“HEAD”。见my answer below

标签: git branch


【解决方案1】:

根据gitrevisions,如果HEADrefs/heads/HEAD都存在,则选择的修订版为HEAD(即不是名为HEAD的分支)。

这实际上是大多数情况的正确答案,但git checkout 更喜欢分支名称而不是修订版本,因此git checkout HEAD 解析为分支,而不是当前提交。

还有其他命令也可以选择分支名称,例如,git branch -f HEAD newrevgit branch -D HEAD 指的是分支,但这里没有真正的歧义空间:git branch 显然在分支上工作。

其他处理程序通常将分支名称或修订说明符传递给 git rev-parsegit rev-list,它们的行为与 gitrevisions 中记录的一样。

请注意,使用更真实的分支名称可能会发生类似情况。就在昨天,我创建了一个用于处理某些以太网项目的分支,并将该分支命名为 e1000 ... 看起来像缩写的 SHA-1。一个名为facade 的分支也遭遇了同样的命运。

【讨论】:

    【解决方案2】:

    好消息是,使用 Git 2.16(2018 年第一季度),这个问题不会再轻易出现了,因为现在 禁止创建名称为“git branch”和“git checkout -b”的分支是“头”

    commit 662a4c8(2017 年 11 月 14 日)Kaartic Sivaraam (sivaraam)
    参见commit a625b09(2017 年 11 月 14 日)和 commit bc1c9c0commit 8280c4c(2017 年 10 月 13 日)Junio C Hamano (gitster)
    (由 Junio C Hamano -- gitster -- 合并到 commit 1616928,2017 年 11 月 28 日)

    branch:正确拒绝refs/heads/{-dash,HEAD}

    strbuf_check_branch_ref() 是许多代码路径的中心位置 看看提议的名称是否适合分公司的名称。
    它旨在让我们比一般用于 refnames 的 check_refname_format() 检查更严格,并且我们已经使用它来拒绝名称以“-”开头的分支。
    该函数获取一个strbuf 和一个字符串“name”,如果名称不适合作为分支的名称,则返回非零值。
    如果名称合适,它会在返回之前将具有建议名称的分支的完整 refname 放在 strbuf 中。

    然而,即使函数返回错误,一个调用者也会查看strbuf 中的内容。
    使函数填充strbuf,即使它返回错误也是如此。
    这样,当“-dash”作为名称给出时,“refs/heads/-dash”在向copy_or_rename_branch()返回错误时被放置在strbuf中,这会注意到用户正在尝试使用“git branch -m -- -dash dash”进行恢复到 将“-dash”重命名为“dash”。

    同时,使用相同的机制来拒绝“HEAD”作为分支名称。

    【讨论】:

      【解决方案3】:

      您可以在需要提交时使用$(git rev-parse --quiet HEAD)(或$(git symbolic-ref HEAD),如果您想知道HEAD“指向”的位置)。

      根据git help rev-parse$GIT_DIR/<refname>优先于refs/HEADrefs/tags/HEADrefs/heads/HEAD等,--quiet将静音“refname 'HEAD' is ambiguous”警告。

      在任何需要 ref 的地方,您都应该能够使用 HEAD 来引用当前签出的“事物”,并使用 refs/heads/HEAD 来引用名为 HEAD 的分支。如果你在 Git 中发现一个地方需要一个 ref(不是一个分支)并且HEAD 不起作用,那么你应该将它报告为一个错误。

      【讨论】:

        最近更新 更多