git submodule update fatal error: reference is not a tree
In addition to Adam Dymitruk's and Michael Chinen's answers, I encountered this problem due to Windows maximum path length. If I try to clone a particular repo that has 3-level deep submodules, in my Documents/Visual Studio 2013/Projects
directory, then I get fatal: reference is not a tree
. But if I repeat the same exact clone in my home directory, it works fine.
Most times it will be the case described by Adam Dymitruk, but another case that can cause this is when switching branches that have submodules that changed remotes. This is because the submodule update just tries to do a checkout of the commit, but it won't be able to before adding and fetching the new remote.
You can verify this by looking at the .gitmodules file and comparing the submodules' URL with the one shown by cd'ing to the submodule and doing a git remote -v
In this case you will need to run git submodule sync
to notify the submodule about the remote change, followed by git submodule update --init --recursive
to get rid of this error.
This is the most common problem with submodules. The commit that you are on in the outer repository has a reference to a commit in the submodule that someone did not push up yet. It's a dependency problem. Always push from the inside-out. This is most likely not something you did wrong, but someone else that's working in the repository. They were sloppy and forgot to issue push on the submodule and just pushed the containing repository. Stuff works on their machine because they made the change and those commits exist there. Go slap them and tell them to push up their submodule changes :)
Otherwise, it could be your fault if you were working on another machine and you forgot to push the submodule changes. Now you're at the other location and are thinking "What is happening! These are my changes and they should work here too!"
The error means that specific commit (its sha1) is not reachable from any of the refs while cloning your submodule, so you should either update your submodule with valid reference or reset the changes to the latest version.
This may happen when you've new commits in your fork, local or you've included references to your detached HEAD, but you haven't push them into your main repository to which submodule git URL points to.
To reset submodule manually to origin/master, enter subdir of submodule and do the reset, e.g.
cd client/src/util
git reset origin/master --hard
If you'd like to correct the reference in the main repo, after doing above commit the changes:
# 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
If you'd like to pull and push the references from fork to origin, you can try:
cd client/src/util # Go to submodule dir again.
git remote add fork [email protected]:example/foo.git
git pull fork master
git show a094dcfeeb43fcd62a9e466156e05e7581026f33 # Check previously missing sha1.
git push origin master:master # Or: master:some_branch