git submodule update致命错误:引用不是树

时间:2012-11-16 22:22:20

标签: git version-control

user$ sudo git submodule update
fatal: reference is not a tree: a094dcfeeb43fcd62a9e466156e05e7581026f33
Unable to checkout 'a094dcfeeb43fcd62a9e466156e05e7581026f33' in submodule path 'client/src/util'

我该怎么办?我只是想从repo中获得最新代码的干净副本,我不介意丢失我的更改。正如您所知,我显然不确定发生了什么。我只能认为它正在尝试签出一个文件,这意味着git检测到本地计算机上文件的本地更改。

我目前正在使用OSX

5 个答案:

答案 0 :(得分:51)

这是子模块最常见的问题。您在外部存储库中进行的提交引用了子模块中有人未提升的提交。这是一个依赖性问题。始终从内到外推动。这很可能不是你做错了,而是在存储库中工作的其他人。它们很草率,忘了在子模块上发出推送,只是推送了包含的存储库。 Stuff在他们的机器上运行,因为他们进行了更改并且那些提交存在于那里。打他们并告诉他们推高他们的子模块变化:)

否则,如果您在另一台机器上工作而忘记推动子模块更改,则可能是您的错。现在你在另一个地方,正在思考“WTF!这些是我的改变,他们也应该在这里工作!”

答案 1 :(得分:23)

大多数情况下,Adam Dymitruk会描述这种情况,但另一种可能导致这种情况的情况是切换具有改变遥控器的子模块的分支。这是因为子模块更新只是尝试检查提交,但是在添加和获取新远程之前它将无法进行。

您可以通过查看.gitmodules文件并将子模块的URL与cd'ing到子模块并执行git remote -v

所显示的URL进行比较来验证这一点。

在这种情况下,您需要运行git submodule sync以通知子模块有关远程更改的信息,然后git submodule update --init --recursive以消除此错误。

答案 2 :(得分:1)

除了Adam Dymitruk和Michael Chinen的回答之外,由于Windows最大路径长度,我遇到了这个问题。如果我尝试在我的Documents/Visual Studio 2013/Projects目录中克隆具有3级深子模块的特定仓库,那么我得到fatal: reference is not a tree。但是,如果我在我的主目录中重复相同的克隆,它可以正常工作。

答案 3 :(得分:1)

错误意味着在克隆子模块时无法从任何引用访问特定提交(其sha1),因此您应该使用有效引用更新子模块或将更改重置为最新版本。

当您在fork中进行新的提交时,可能会发生这种情况,或者您已经包含了对已分离的HEAD的引用,但是您没有将它们推送到子模块git URL所指向的主存储库中。

要手动将子模块重置为origin / master,请输入submodule的subdir并进行重置,例如

cd client/src/util
git reset origin/master --hard

如果您想更正主仓库中的参考,请在执行上述提交后进行更改:

# Still in submodule dir.
git pull origin master # In submodule dir.
git push origin master
cd - # Go back to the main repo dir.
git status
git commit -am 'Update submodule refs'
git push

如果您想将引用从fork转移到origin,可以尝试:

cd client/src/util # Go to submodule dir again.
git remote add fork git@github.com:example/foo.git
git pull fork master
git show a094dcfeeb43fcd62a9e466156e05e7581026f33 # Check previously missing sha1. 
git push origin master:master # Or: master:some_branch

答案 4 :(得分:0)

您的子模块存储库很可能没有引用外部存储库的修订。它也可能在子模块指定的遥控器上不可用,或者您没有为子模块进行远程设置。您可以尝试进入client/src/utilgit fetch

(为什么你sudo?如果它属于root,为什么你不在root shell中,如果不是,为什么你改成root?)