4

通常,当您在 git 存储库中运行类似这样的内容时:

git checkout abc1234

您最终处于分离的 HEAD 状态。如果运行git branch,输出将如下所示:

* (detached from abc1234)
  master

这是很好的预期行为。

我最近一直在玩 pygit2,并且遇到了一些我以前没见过的东西。假设我执行以下操作:

repo = pygit2.discover_repository("/path/to/repo")
repo.head = "abc1234"

我希望存储库处于分离的 HEAD 状态。出于所有意图和目的,我相信这是在这样做之后。但是,输出git branch看起来有点不同:

* (no branch)
  master

有谁知道区别是什么,为什么会有区别,以及这意味着什么?

编辑:

下面是使用 pygit2 克隆存储库后的 reflog,将提交 SHA1 哈希分配给 repo.head,然后运行git checkout master,然后运行git checkout myhash

69df316 HEAD@{0}: checkout: moving from master to 69df3161f315e9b13ba4bd811635c11f67616598
d6ece61 HEAD@{1}: checkout: moving from 69df3161f315e9b13ba4bd811635c11f67616598 to master
69df316 HEAD@{2}:
d6ece61 HEAD@{3}: clone: from file:///path/to/repo
4

3 回答 3

5

当处于“分离的 HEAD”状态时,git 将根据 reflog 条目的内容显示“(无分支)”或“(从 abc 分离)”。

在您的代码中,您只需覆盖该值而不提供任何消息,因此不会将任何消息写入 reflog(如您在HEAD@{2}reflog 的条目中所见)。如果有类似的“结帐”消息,则会出现分离的文本。

pygit2 提供Reference.log_append()将条目附加到日志,因此您可以创建这样的条目,尽管目前它仍会创建空条目)。解决方案是在更新方法支持 libgit2 0.21 中引入的更新的 reflog 处理后使用它。

参考设置方法Reference.set_target()Repository.set_head()提供了一个放置您自己的身份和消息的位置 reflog,您可以使用它来提供等效于 git 的 checkout 命令将创建的消息。

您可以尝试按照目前的方式进行更新,并在 reflog 中手动写入条目(它位于 .git/logs/HEAD 下,它是一个文本文件)以模仿 git 将写入的内容,您应该会看到“(与 abc 分离) )”消息出现。

于 2014-08-27T17:18:25.103 回答
2

Git 在第一个示例中表明您已签出提交(不是分支),因此您的头已分离。

在第二个示例中,Git 表明您签出了无效的内容。你没有处于分离的 HEAD 状态,你的 HEAD 指向一个无效的分支,特别是它指向一个带有你的提交 ID 名称的分支。

您为 指定了一个字符串参数repo.head,就好像它是一个分支名称一样。(并且 pygit 尽职尽责地将 HEAD 设置为不存在的分支名称。)相反,您需要指定一个Oid,以指示应该分离头部:

repo.head = Oid(hex="abc1234...")
于 2014-08-23T13:37:06.277 回答
1

检查两种情况下的 git 版本是否相同。Junio C Hamano
的文章“以编程方式检查当前分支”指出:

事实上,从 1.8.3 版本开始,当你不在任何分支上时,输出变成了这样:

$ git checkout v1.8.3
$ git branch
* (detached from v1.8.3)
  master
  next

这意味着第二个输出“ (no branch)”与使用 git pre-1.8.3 一致,或者与pygit2使用旧版本libgit2的事实一致,正如Jean Hominal所评论的那样


如果这是由同一个 git 生成的,请检查以下内容HEAD:参见“用户手册

then 指的HEAD是提交的 SHA-1 而不是分支,并且 git branch 显示您不再在分支上:

$ cat .git/HEAD
427abfa28afedffadfca9dd8b067eb6d36bac53f
$ git branch
* (detached from v2.6.17)
master

但是,在第二种情况下,如果 pygit2 根本没有设置HEADwt_status.c则会显示no branch.

于 2014-08-23T08:49:19.880 回答