Git的问题(HEAD指向未出生的分支(主))

时间:2011-12-18 11:01:50

标签: git

我有一个带有'master'分支的Git存储库。 不久前(几个月),我们停止使用master,并创建了一个新分支,所有工作都在进行中。

我现在正在使用git设置源索引,出于某种原因,我看到了新分支的奇怪内容:

  1. 运行 git log 失败:

      

    致命:错误的默认修订'HEAD'

  2. 运行 git fsck 会产生以下结果:

      

    注意:HEAD指向未出生的分支(主)通知:无默认值   引用悬空提交81f11e0b99ad38ecc8502bbed171d2bdfcaa6476

  3. 我认为这个存储库/分支有些不对,这会导致源索引脚本出现问题。

    有什么想法吗? (请注意,这里的REAL问题是源索引脚本无法获取它尝试使用git show查找的对象ID,它表示不存在此类对象。)

3 个答案:

答案 0 :(得分:10)

您不必拥有主分支,但您必须在任何git存储库中拥有“默认”分支。在非裸存储库中这个已检出的分支,在裸存储库中它只是意味着它是克隆的默认分支。

此默认分支称为HEAD,必须始终存在于有效的git存储库中。如果您删除了HEAD指向的分支,则可以将其重置为有效分支:

git symbolic-ref HEAD refs/heads/new-main-branch

答案 1 :(得分:0)

这是由于某些损坏而发生在我身上的,@ CBBailey的回答起初没有起作用。

要修复以前从工作克隆中推送的损坏,例如:

git push origin :refs/heads/master

这导致裸仓库的refs/heads/目录为空,因此为什么我遇到HEAD指向“未出生分支”的问题。就我而言,这可以通过再做一次来解决:

git push --all

这将refs/heads/master重新放回原位,因此HEAD再次工作。

答案 2 :(得分:0)

<块引用>

在非裸仓库中,这是签出的分支,在裸仓库中,它只是意味着它是为克隆签出的默认分支。

Git 现在会知道该默认分支是否尚不存在。

在 Git 2.31(2021 年第一季度)中,“git clone(man) 尝试在本地检出远程存储库的 HEAD 指向的分支后完成,但协议没有传达复制空存储库所需的信息。
协议 v2 学会了如何做到这一点。

commit 4f37d45commit 3983540commit 59e1205Jonathan Tan (jhowtan)(2021 年 2 月 5 日)。
(2021 年 2 月 17 日在 Junio C Hamano -- gitster --commit 69571df 合并)

<块引用>

ls-refs:报告未出生的 symrefs 目标

签字人:Jonathan Tan

<块引用>

克隆时,我们根据远程HEAD选择默认分支。
但是如果没有远程 HEAD 报告(如果远程 HEAD 的目标未出生,可能会发生这种情况),我们将回退到使用我们的本地 init.defaultBranch

(这就是CB Baileyanswer提到的)

<块引用>

传统上这没什么大不了的,因为大多数存储库使用“master”作为默认值。

但是现在如果服务器和客户端实现选择不同的值可能会引起混淆(例如,如果远程以“main”开头,我们可能会在本地选择“master”,创建在那里提交,然后当他们推送到“master”而不是“main”时用户会感到惊讶)。

为了解决这个问题,远程需要与 HEAD symref 的目标通信,即使它是未出生的,和 "git clone"(man) 需要使用这些信息。

目前,具有未出生目标(例如在本例中)的 symrefs 不会通过协议进行通信。

教 Git 宣传和支持“ls-refs”中的“未出生”功能(默认情况下,这是宣传的,但服务器管理员可以通过 lsrefs.unborn 配置将其关闭)。
该特性表明“ls-refs”支持“unborn”参数;指定时,“ls-refs”将发送 HEAD symref 及其未出生目标的名称。

此更改仅适用于协议 v2。
协议 v0 的类似更改将需要独立的协议设计(没有类似的位置来表示对“未出生”的信号支持)和所需数据的客户端管道,因此此补丁集的范围仅限于协议 v2。

客户端将更新以在后续提交中使用它。

git config 现在包含在其 man page 中:

<块引用>

lsrefs.unborn

可能是“advertise”(默认值)、“allow”或“ignore”。
如果“做广告”, 服务器将响应客户端发送“unborn”(如 protocol-v2.txt) 并将在此期间宣传对此功能的支持 协议 v2 能力公告。
allow”与 “advertise”,除了服务器不会宣传对此的支持 特征;这对于不能被负载平衡的服务器很有用 自动更新(例如),因为管理员可以 配置“allow”,然后延迟一段时间后,配置“advertise”。

technical/protocol-v2 现在包含在其 man page 中:

<块引用>

如果广告“unborn”功能,则可以使用以下参数 包含在客户的请求中。

unborn
即使是 symref,服务器也会发送有关 HEAD 的信息 指向形式为“unborn HEAD symref-target:<target>”的未出生分支。

technical/protocol-v2 现在包含在其 man page 中:

<块引用>

obj-id-or-unborn = (obj-id | "unborn")
ref = PKT-LINE(obj-id-or-unborn SP refname *(SP ref-attribute) LF)


同样,此功能仅在使用协议 v2 时可用,如 Git 2.31.1(2021 年第一季度)所示:

请参阅 commit 5f70859Jonathan Tan (jhowtan)(2021 年 3 月 17 日)。
(由 Junio C Hamano -- gitster --commit cc930b7 合并,2021 年 3 月 19 日)

<块引用>

t5606:使用协议 v2 运行克隆分支名称测试

签字人:Jonathan Tan

<块引用>

4f37d45(“clone:尊重远程未出生的 HEAD”,2021-02-05,Git v2.31.0-rc0 -- merge 列于 batch #9)介绍一个新功能(如果远程有一个未出生的 HEAD,例如当远程存储库为空时,将其用作分支的名称)仅适用于协议 v2,但并不能确保其一个测试始终使用协议 v2,因此,如果使用 GIT_TEST_PROTOCOL_VERSION=0(或 1),该测试将失败。
因此,将“-c protocol.version=2”添加到相应的测试中。

Example

git -c init.defaultBranch=foo init --bare empty
git -C empty config lsrefs.unborn advertise
git -c init.defaultBranch=up -c protocol.version=2 clone empty whats-up

本地克隆存储库 (git -C whats-up symbolic-ref HEAD) 的默认分支名称不会是 up(即使 init.defaultBranch 被明确设置为“up”),但是无论远程(空)存储库的默认名称是什么:在本例中为“foo”(因为远程存储库已将 lsrefs.unborn 设置为 advertise