git子模块更新致命错误:引用不是树

git子模块更新致命错误:引用不是树,git,version-control,Git,Version Control,我该怎么办?我只想从回购协议中获得最新代码的清晰副本,我不介意丢失我的更改。正如您所知,我显然不知道发生了什么。我只能认为它正在尝试签出一个文件,这意味着git在我的本地机器上检测到一个文件的本地更改 我目前正在使用OSX,很可能您的子模块存储库没有外部存储库引用的修订版。它也可能在为子模块指定的远程位置不可用,或者您没有为子模块进行远程设置。您可以尝试进入那里的client/src/util和git fetch (为什么要sudoit?如果它属于root,为什么不在root shell中,如果

我该怎么办?我只想从回购协议中获得最新代码的清晰副本,我不介意丢失我的更改。正如您所知,我显然不知道发生了什么。我只能认为它正在尝试签出一个文件,这意味着git在我的本地机器上检测到一个文件的本地更改


我目前正在使用OSX,很可能您的子模块存储库没有外部存储库引用的修订版。它也可能在为子模块指定的远程位置不可用,或者您没有为子模块进行远程设置。您可以尝试进入那里的
client/src/util
git fetch


(为什么要
sudo
it?如果它属于root,为什么不在root shell中,如果不在root shell中,为什么要更改为root?

这是子模块最常见的问题。您在外部存储库中进行的提交有一个对子模块中的提交的引用,该子模块中有人尚未提交。这是一个依赖性问题。总是从里往外推。这很可能不是您做错了什么,而是正在存储库中工作的其他人。他们太草率了,忘记了对子模块进行推送,只是推送了包含的存储库。东西在他们的机器上工作,因为他们做出了改变,并且这些承诺存在于那里。去打他们一巴掌,告诉他们推进子模块的更改:)


否则,如果您在另一台机器上工作时忘记推动子模块更改,则可能是您的错误。现在,您在另一个位置,正在思考“发生了什么事!这些是我的更改,它们也应该在这里工作!”

大多数情况下,亚当·迪米特鲁克(Adam Dymitruk)描述了这种情况,但另一种可能导致这种情况的情况是,切换具有更改远程的子模块的分支时。这是因为子模块更新只是尝试对提交进行签出,但在添加和获取新的远程数据之前,它将无法进行签出

您可以通过查看.gitmodules文件并将子模块的URL与通过cd'ing对子模块显示的URL进行比较,然后执行
git remote-v


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

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

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

当您在fork、local中有新的提交,或者包含了对分离头的引用,但尚未将它们推送到子模块git URL指向的主存储库时,可能会发生这种情况

要手动将子模块重置为原始/主模块,请输入子模块的subdir并执行重置,例如

user$ sudo git submodule update
fatal: reference is not a tree: a094dcfeeb43fcd62a9e466156e05e7581026f33
Unable to checkout 'a094dcfeeb43fcd62a9e466156e05e7581026f33' in submodule path 'client/src/util'
如果要更正主回购中的引用,请在执行上述操作后提交更改:

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

如果要将引用从fork拉入并推送到原点,可以尝试:

# 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

我使用的是mac电脑,默认情况下,我必须
sudo
writes@bouncingHippo,不,mac不需要sudo,除非你把权限搞砸了。因此,您必须:)我必须推送子模块更改,还是有办法忽略子模块更改?您不能发出子模块更新命令。但是如果你有依赖于此的代码,事情就不会发生了。对我来说,这不是问题的原因。我完全推动了子模块的提交。我可以在我想要的任何机器上手动克隆外部模块并“更新”子模块。但在我设置的VisualStudio.com云构建代理上,它失败并显示相同的错误消息。不知道为什么。这个答案涵盖了一个狭窄的场景。如果子模块来自第三方来源(通用),并且更改已在本地发布到该第三方子模块,那么它们实际上无法始终提交,因为它们将提交给第三方回购。所以我在这个场景中,除了我不能在子模块上从本地提交我的更改外,我只想忽略它们。但我仍然需要在生产中引入子模块,但我得到了那个错误。这正是我的问题所在——我没有推动子模块提交。Git的可能副本与其用户存在敌对关系。谢谢你这次帮我赢了。
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