通常在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,为repo.head分配提交SHA1哈希,然后运行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
答案 0 :(得分:5)
当处于“分离的HEAD”状态时,git将显示“(无分支)”或“(与abc分离)”,具体取决于reflog条目的内容。
在您的代码中,您只需覆盖该值而不提供任何消息,因此不会向reflog写入任何消息(您可以在reflog的HEAD@{2}
条目中看到)。如果有类似的“结帐”消息,则会显示分离的文本。
pygit2提供 Reference.log_append()
将条目附加到日志中,因此您可以创建这样的条目,但是目前它仍然会创建空条目。一旦它支持libgit2 0.21中引入的更新的reflog处理,解决方案就是使用update方法。
引用设置方法Reference.set_target()
和Repository.set_head()
为reflog提供了一个放置自己的标识和消息的位置,您可以使用它来提供与git的checkout命令相同的消息
您可以尝试以当前的方式进行更新,并手动编写reflog中的条目(它位于.git / logs / HEAD下,它是一个文本文件)来模仿git会写什么,你应该看到“(与abc分离)“消息出现。
答案 1 :(得分:2)
Git在第一个示例中指出您已签出提交(而不是分支),因此您的头部已分离。
在第二个例子中,Git表示您已检查出无效的内容。你没有处于分离的HEAD状态,你的HEAD指向一个无效的分支,特别是它指向一个带有你的提交ID名称的分支。
您为repo.head
指定了一个字符串参数,就好像它是一个分支名称。 (并且pygit尽职尽责地将HEAD设置为不存在的分支名称。)相反,您需要指定Oid,以指示应该分离头部:
repo.head = Oid(hex="abc1234...")
答案 2 :(得分:1)
检查两种情况下git的版本是否相同 文章" Checking the current branch programatically"来自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,commented Jean Hominal {/ 3}}的情况一致
如果这是由相同的git生成的,请检查HEAD
的内容:请参阅" user manual"
HEAD
然后引用提交的SHA-1而不是分支,git分支显示你不再在分支上:
$ cat .git/HEAD
427abfa28afedffadfca9dd8b067eb6d36bac53f
$ git branch
* (detached from v2.6.17)
master
但是,在第二种情况下,如果pygit2根本没有设置HEAD
,则wt_status.c
会显示no branch
。