git Git子模块头“引用不是树”错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2155887/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 07:45:26  来源:igfitidea点击:

Git submodule head 'reference is not a tree' error

gitgit-submodules

提问by Mauricio Scheffer

I have a project with a submodule that is pointing to an invalid commit: the submodule commit remained local and when I try to fetch it from another repo I get:

我有一个带有指向无效提交的子模块的项目:子模块提交仍然是本地的,当我尝试从另一个存储库中获取它时,我得到:

$ git submodule update
fatal: reference is not a tree: 2d7cfbd09fc96c04c4c41148d44ed7778add6b43
Unable to checkout '2d7cfbd09fc96c04c4c41148d44ed7778add6b43' in submodule path 'mysubmodule'

I know what the submodule HEAD should be, is there any way I can change this locally, without pushing from the repo that doeshave commit 2d7cfbd09fc96c04c4c41148d44ed7778add6b43?

我知道子模块HEAD应该是什么,有什么办法,我可以在当地改变这一状况,在不脱离回购推确实已经提交2d7cfbd09fc96c04c4c41148d44ed7778add6b43

I'm not sure if I'm being clear... here's a similar situationI found.

我不确定我是否清楚......这是我发现的类似情况

回答by Chris Johnsen

Assuming the submodule's repository does contain a commit you want to use (unlike the commit that is referenced from current state of the super-project), there are two ways to do it.

假设子模块的存储库确实包含您要使用的提交(与从超级项目的当前状态引用的提交不同),有两种方法可以做到。

The first requires you to already know the commit from the submodule that you want to use. It works from the “inside, out” by directly adjusting the submodule then updating the super-project. The second works from the “outside, in” by finding the super-project's commit that modified the submodule and then reseting the super-project's index to refer to a different submodule commit.

第一个要求您已经知道要使用的子模块的提交。通过直接调整子模块然后更新超级项目,从“内、外”开始工作。第二个从“外部,内部”开始,通过查找修改子模块的超级项目提交,然后重置超级项目的索引以引用不同的子模块提交。

Inside, Out

反了

If you already know which commit you want the submodule to use, cdto the submodule, check out the commit you want, then git addand git commitit back in the super-project.

如果你已经知道其呈交你想要的子模块来使用,cd子模块,请提交你想要的,然后git addgit commit它放回超级项目。

Example:

例子:

$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'

Oops, someone made a super-project commit that refers to an unpublished commit in the submodule sub. Somehow, we already know that we want the submodule to be at commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c. Go there and check it out directly.

糟糕,有人做了一个超级项目提交,它指的是 submodule 中未发布的提交sub。不知何故,我们已经知道我们希望子模块处于 commit 状态5d5a3ee314476701a20f2c6ec4a53f88d651df6c。去那里直接检查。

Checkout in the Submodule

在子模块中结帐

$ cd sub
$ git checkout 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
Note: moving to '5d5a3ee314476701a20f2c6ec4a53f88d651df6c' which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b <new_branch_name>
HEAD is now at 5d5a3ee... quux
$ cd ..

Since we are checking out a commit, this produces a detached HEAD in the submodule. If you want to make sure that the submodule is using a branch, then use git checkout -b newbranch <commit>to create and checkout a branch at the commit or checkout the branch that you want (e.g. one with the desired commit at the tip).

由于我们正在检查提交,这会在子模块中产生一个分离的 HEAD。如果你想确保子模块正在使用一个分支,那么使用git checkout -b newbranch <commit>在提交时创建和签出一个分支或签出你想要的分支(例如,在提示处带有所需提交的分支)。

Update the Super-project

更新超级项目

A checkout in the submodule is reflected in the super-project as a change to the working tree. So we need to stage the change in the super-project's index and verify the results.

子模块中的检出反映在超级项目中作为对工作树的更改。所以我们需要对超级项目的索引进行阶段性的变化并验证结果。

$ git add sub

Check the Results

检查结果

$ git submodule update
$ git diff
$ git diff --cached
diff --git c/sub i/sub
index e47c0a1..5d5a3ee 160000
--- c/sub
+++ i/sub
@@ -1 +1 @@
-Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c

The submodule update was silent because the submodule is already at the specified commit. The first diff shows that the index and worktree are the same. The third diff shows that the only staged change is moving the subsubmodule to a different commit.

子模块更新是静默的,因为子模块已经在指定的提交中。第一个差异表明索引和工作树是相同的。第三个差异显示唯一的阶段性更改是将sub子模块移动到不同的提交。

Commit

犯罪

git commit

This commits the fixed-up submodule entry.

这将提交固定的子模块条目。



Outside, In

外面,里面

If you are not sure which commit you should use from the submodule, you can look at the history in the superproject to guide you. You can also manage the reset directly from the super-project.

如果您不确定应该使用子模块中的哪个提交,您可以查看超级项目中的历史记录来指导您。您也可以直接从超级项目管理重置。

$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'

This is the same situation as above. But this time we will focus on fixing it from the super-project instead of dipping into the submodule.

这和上面的情况是一样的。但是这次我们将专注于从超级项目中修复它,而不是深入到子模块中。

Find the Super-project's Errant Commit

找到超级项目的错误提交

$ git log --oneline -p -- sub
ce5d37c local change in sub
diff --git a/sub b/sub
index 5d5a3ee..e47c0a1 160000
--- a/sub
+++ b/sub
@@ -1 +1 @@
-Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
+Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
bca4663 added sub
diff --git a/sub b/sub
new file mode 160000
index 0000000..5d5a3ee
--- /dev/null
+++ b/sub
@@ -0,0 +1 @@
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c

OK, it looks like it went bad in ce5d37c, so we will restore the submodule from its parent (ce5d37c~).

好的,看起来它在 中坏了ce5d37c,所以我们将从其父模块 ( ce5d37c~)恢复子模块。

Alternatively, you can take the submodule's commit from the patch text (5d5a3ee314476701a20f2c6ec4a53f88d651df6c) and use the above “inside, out” process instead.

或者,您可以从补丁文本 ( 5d5a3ee314476701a20f2c6ec4a53f88d651df6c) 中获取子模块的提交,并改用上述“内、外”过程。

Checkout in the Super-project

在超级项目中签出

$ git checkout ce5d37c~ -- sub

This reset the submodule entry for subto what it was at commit ce5d37c~in the super-project.

这将子模块条目重置为subce5d37c~在超级项目中提交时的内容。

Update the Submodule

更新子模块

$ git submodule update
Submodule path 'sub': checked out '5d5a3ee314476701a20f2c6ec4a53f88d651df6c'

The submodule update went OK (it indicates a detached HEAD).

子模块更新正常(它表示分离的 HEAD)。

Check the Results

检查结果

$ git diff ce5d37c~ -- sub
$ git diff
$ git diff --cached
diff --git c/sub i/sub
index e47c0a1..5d5a3ee 160000
--- c/sub
+++ i/sub
@@ -1 +1 @@
-Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c

The first diff shows that subis now the same in ce5d37c~. The second diff shows that the index and worktree are the same. The third diff shows the only staged change is moving the subsubmodule to a different commit.

第一个差异显示sub现在在ce5d37c~. 第二个差异表明索引和工作树是相同的。第三个差异显示唯一的阶段性更改是将sub子模块移动到不同的提交。

Commit

犯罪

git commit

This commits the fixed-up submodule entry.

这将提交固定的子模块条目。

回答by Lonre Wang

try this:

尝试这个:

git submodule sync
git submodule update

回答by Daniel Tsadok

This error can mean that a commit is missing in the submodule. That is, the repository (A) has a submodule (B). A wants to load B so that it is pointing to a certain commit (in B). If that commit is somehow missing, you'll get that error. Once possible cause: the reference to the commit was pushed in A, but the actual commit was not pushed from B. So I'd start there.

此错误可能意味着子模块中缺少提交。也就是说,存储库 (A) 有一个子模块 (B)。A 想要加载 B,以便它指向某个提交(在 B 中)。如果该提交以某种方式丢失,您将收到该错误。曾经可能的原因:对提交的引用被推送到 A 中,但实际提交不是从 B 推送的。所以我会从那里开始。

Less likely, there's a permissions problem, and the commit cannot be pulled (possible if you're using git+ssh).

不太可能的是,存在权限问题,并且无法拉取提交(如果您使用的是 git+ssh,则可能)。

Make sure the submodule paths look ok in .git/config and .gitmodules.

确保 .git/config 和 .gitmodules 中的子模块路径正常。

One last thing to try - inside the submodule directory: git reset HEAD --hard

最后一件事要尝试 - 在子模块目录中: git reset HEAD --hard

回答by chriskelly

Possible cause

可能的原因

This can happens when:

这可能发生在:

  1. Submodule(s) have been edited in place
  2. Submodule(s) committed, which updates the hash of the submodule being pointed to
  3. Submodule(s) not pushed.
  1. 子模块已就地编辑
  2. 已提交的子模块,更新所指向的子模块的哈希值
  3. 子模块未推送

e.g. something like this happened:

例如这样的事情发生了:

$ cd submodule
$ emacs my_source_file  # edit some file(s)
$ git commit -am "Making some changes but will forget to push!"

Should have submodule pushed at this point.

此时应该推送子模块。

$ cd .. # back to parent repository
$ git commit -am "updates to parent repository"
$ git push origin master

As a result, the missing commits could not possibly be found by the remote user because they are still on the local disk.

结果,远程用户不可能找到丢失的提交,因为它们仍在本地磁盘上。

Solution

解决方案

Informa the person who modified the submodule to push, i.e.

通知修改子模块的人进行推送,即

$ cd submodule
$ git push

回答by Plato

I got this error when I did:

我这样做时遇到了这个错误:

$ git submodule update --init --depth 1

but the commit in the parent project was pointing at an earlier commit.

但父项目中的提交指向较早的提交。

Deleting the submodule folder and running:

删除子模块文件夹并运行:

$ git submodule update --init

did NOT solve the problem. I deleted the repo and tried again without the depth flag and it worked.

没有解决问题。我删除了 repo 并在没有深度标志的情况下再次尝试并且它起作用了。

This error happens in Ubuntu 16.04 git 2.7.4, but not on Ubuntu 18.04 git 2.17, TODO find exact fixing commit or version.

此错误发生在 Ubuntu 16.04 git 2.7.4 中,但不会发生在 Ubuntu 18.04 git 2.17 上,TODO 找到确切的修复提交或版本。

回答by pasamio

This may also happen when you have a submodule pointing to a repository that was rebased and the given commit is "gone". While the commit may still be in the remote repository, it is not in a branch. If you can't create a new branch (e.g. not your repository), you're stuck with having to update the super project to point to a new commit. Alternatively you can push one of your copies of the submodules elsewhere and then update the super-project to point to that repository instead.

当您有一个子模块指向一个重新定位的存储库并且给定的提交“消失”时,也可能发生这种情况。虽然提交可能仍在远程存储库中,但它不在分支中。如果您无法创建新分支(例如不是您的存储库),您将不得不更新超级项目以指向新提交。或者,您可以将子模块的一个副本推送到其他地方,然后更新超级项目以指向该存储库。

回答by kittycatbytes

Your branch may not be up to date, a simple solution but try git fetch

您的分支可能不是最新的,这是一个简单的解决方案,但请尝试 git fetch

回答by ericTbear

This answer is for users of SourceTree with limited terminal git experience.

此答案适用于终端 git 经验有限的 SourceTree 用户。

Open the problematic submodule from within the Git project (super-project).

从 Git 项目(超级项目)中打开有问题的子模块。

Fetch and ensure 'Fetch all tags' is checked.

获取并确保选中“获取所有标签”。

Rebase pull your Git project.

Rebase 拉取你的 Git 项目。

This will solve the 'reference is not a tree' problem 9 out of ten times. That 1 time it won't, is a terminal fix as described by the top answer.

这将解决十次中有九次“引用不是树”的问题。1 次不会,是顶级答案所描述的终端修复。

回答by An Phan

Just stumbled upon this problem, and none of these solutions worked for me. What turned out to be the solution for my issue is actually much simpler: upgrade Git. Mine was 1.7.1, and after I upgraded it to 2.16.1 (latest), the problem went away without a trace! Guess I'm leaving it here, hope it helps someone.

只是偶然发现了这个问题,但这些解决方案都不适合我。结果证明我的问题的解决方案实际上要简单得多:升级 Git。我的是1.7.1,升级到2.16.1(最新)后,问题就消失了!猜猜我要把它留在这里,希望它可以帮助某人。

回答by Lakshman Prasad

Your submodule history is safely preserved in the submodule git anyway.

无论如何,您的子模块历史记录都安全地保存在子模块 git 中。

So, why not just delete the submodule and add it again?

那么,为什么不删除子模块并重新添加它呢?

Otherwise, did you try manually editing the HEADor the refs/master/headwithin the submodule .git

否则,您是否尝试在子模块中手动编辑HEAD或 ?refs/master/head.git