我有一个带有'master'分支的Git存储库。 不久前(几个月),我们停止使用master,并创建了一个新分支,所有工作都在进行中。
我现在正在使用git设置源索引,出于某种原因,我看到了新分支的奇怪内容:
运行 git log 失败:
致命:错误的默认修订'HEAD'
运行 git fsck 会产生以下结果:
注意:HEAD指向未出生的分支(主)通知:无默认值 引用悬空提交81f11e0b99ad38ecc8502bbed171d2bdfcaa6476
我认为这个存储库/分支有些不对,这会导致源索引脚本出现问题。
有什么想法吗? (请注意,这里的REAL问题是源索引脚本无法获取它尝试使用git show查找的对象ID,它表示不存在此类对象。)
答案 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 4f37d45的commit 3983540、commit 59e1205、Jonathan Tan (jhowtan
)(2021 年 2 月 5 日)。
(2021 年 2 月 17 日在 Junio C Hamano -- gitster
-- 被 commit 69571df 合并)
ls-refs
:报告未出生的 symrefs 目标签字人:Jonathan Tan
<块引用>克隆时,我们根据远程HEAD选择默认分支。
但是如果没有远程 HEAD 报告(如果远程 HEAD 的目标未出生,可能会发生这种情况),我们将回退到使用我们的本地 init.defaultBranch
。
传统上这没什么大不了的,因为大多数存储库使用“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 5f70859 的 Jonathan 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
”添加到相应的测试中。
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
)