git2go';s CheckoutHead()未更新索引

git2go';s CheckoutHead()未更新索引,git,go,libgit2,Git,Go,Libgit2,我试图在现有目录上初始化存储库,添加一个远程服务器,并在现有文件上强制签出远程服务器的主分支。用于此操作的cli命令为: git init。 git添加远程源'https://domain/repo.git' git获取 git签出-f源/主 一切正常,但在签出后索引似乎没有改变。有关守则如下: #(init repo,添加“origin”遥控器并获取它…) 报告设定头(“参考/遥控/原点/主控”) repo.CheckoutHead(&git.CheckoutOpts{Strategy:gi

我试图在现有目录上初始化存储库,添加一个远程服务器,并在现有文件上强制签出远程服务器的主分支。用于此操作的cli命令为:

git init。
git添加远程源'https://domain/repo.git'
git获取
git签出-f源/主
一切正常,但在签出后索引似乎没有改变。有关守则如下:

#(init repo,添加“origin”遥控器并获取它…)
报告设定头(“参考/遥控/原点/主控”)
repo.CheckoutHead(&git.CheckoutOpts{Strategy:git.CheckoutForce})
当我执行
git status
时,我会看到索引中显示为已删除(D)的文件和未跟踪的文件(是的,相同的文件显示为两者),而workdir确实包含正确的文件。由于这看起来像是索引没有从内存写入磁盘,或者有一些奇怪的缓存,我在签出后也尝试了
index.Write()
,但没有做任何更改

如果我在repo中运行
git reset HEAD
,那么
git status
会返回一个干净的状态,因为索引会更新到当前HEAD树,现在它会反映workdir

更新 我注意到只有当现有目录中的文件与originrepo中的文件相同时才会发生这种情况(文件模式并不重要)。在这种情况下,这些文件显示为已删除(D)和未跟踪(?)


当文件存在但内容不同时,不会发生这种情况。在这种情况下,文件正确地显示为已修改(M)。

我通过将树读入索引并在签出之前将索引写入磁盘来解决它。代码如下所示:

repo.SetHead("refs/remotes/origin/master")
# get the index and the HEAD tree...
index.ReadTree(headTree)
index.Write()
repo.CheckoutHead(&git.CheckoutOpts{Strategy: git.CheckoutForce})
这似乎与运行
git checkout-f origin/master
具有相同的效果。但是我不知道为什么需要,因为应该更新索引和工作树:

git\u签出\u头
更新索引和工作树中的文件,以匹配HEAD指向的提交内容


我最好的猜测是签出无法正常工作,因为索引最初指向一个空树。但是,我不确定这是否是libgit2错误。

在检查我们的工作目录之前不要更新
标题,否则您的工作目录将变脏,并且(可能)无法继续签出。而是签出到您想要的内容,如果签出成功,则更新
HEAD

比如:

target, err := repo.LookupCommit(newHeadId)
repo.CheckoutTree(target, &git.CheckoutOpts{Strategy: git.CheckoutSafe})
_, err = repo.References.Create("refs/heads/master", commitId, true, "master")

谢谢,是的,我注意到这个方法是有效的,但是
git\u checkout\u head()
说它更新了索引和工作树,所以我希望它的工作方式类似于
git checkout-f head
(特别是在使用--force时),为什么不是这样呢?另外,如果我有一个已经脏了的工作树,并且我想将该工作树与索引同步,就像我使用
git checkout-f
所做的那样,该怎么办?在我看来,
git\u checkout\u head()
是非常无用的(至少使用--force)。它确实更新了索引和工作树。您的示例(上面)显示了
git checkout-f
,然后尝试将其与
git_checkout_head
等同起来;它们不一样。如果您发现
git\u checkout\u head
git checkout-f head
之间存在差异(当遵循相同的步骤时),请在进一步的问题或问题中阐明这一点。好的。我看到了
git checkout-f HEAD
git\u checkout\u HEAD()
之间的差异,因此我将创建一个可复制的测试用例,并在libgit2中打开一个问题(但使用git2go对我来说更容易)。谢谢。我也不明白为什么
git\u checkout\u head
的文档会说它会更新索引和工作树,以匹配head指向的提交,而它显然不会。asandroq绝对会这样做。问题是,当您在签出之前更改
头时,您的工作树现在变脏了。您将看到,如果您任意更改
,然后运行
git status
。如果您随后执行一个
git签出头
,它将尝试签出该数据,但不能保证它能签出,因为您的工作树是脏的。在原始状态下执行签出,如果成功,则更新
HEAD
。我们更新了文档以更好地解释这一点。