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

What do I do? I just want to get a clean copy of the latest code from the repo, i dont mind losing my changes. As you can tell, I clearly am not sure what is happening. I can only think that it is trying to checkout a file which means git detected a local change in a file on my local machine.

i am currently using OSX

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
bouncingHippo
  • 5,940
  • 21
  • 67
  • 107
  • possible duplicate of [Git submodule head 'reference is not a tree' error](http://stackoverflow.com/questions/2155887/git-submodule-head-reference-is-not-a-tree-error) – Chris Moschini Aug 29 '14 at 18:40

5 Answers5

62

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!"

Roel Van de Paar
  • 2,111
  • 1
  • 24
  • 38
Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
  • must i push the submodule changes, or is there a way to ignore the submodule change?s – bouncingHippo Nov 17 '12 at 02:47
  • you can just not issue the submodule update command. But if you have code depending on that, things won't work. – Adam Dymitruk Nov 17 '12 at 05:52
  • 1
    This isn't the cause of the problem for me. I have absolutely pushed the commit of the submodule. I can manually clone the outer and 'update' the submodule on any machine I wish. But on the VisualStudio.com cloud build agent that I've set up, it fails with the same error message. No idea why. – Andrew Arnott Sep 21 '14 at 22:01
  • 6
    This answer covers a narrow scenario. If the submodule was from a 3rd party source (common), and changes have been issued locally to that third party submodule then they can't actually always be committed, as they'd be committing them to the 3rd party repo. So I'm in this scenario, except I cannot commit my changes from local on the submodule, I just wish to ignore them. But I still need to pull in the submodule in production, but am getting that error. – Nathan Hornby Feb 06 '15 at 14:04
  • This is exactly what my problem was--I hadn't pushed the submodule commit. – NRitH Jun 27 '20 at 19:13
28

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.

Michael Chinen
  • 17,737
  • 5
  • 33
  • 45
  • Git has an adversarial relationship with its users. Thank you for helping me win, this time. – weberc2 Jun 29 '17 at 18:32
  • changing remote repository in .gitsubmodule caused this and `git submodule sync` helped resolve the issue. Thanks a ton! – Mahesh Jan 24 '22 at 16:58
2

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.

Edward Ned Harvey
  • 6,525
  • 5
  • 36
  • 45
2

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 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
kenorb
  • 155,785
  • 88
  • 678
  • 743
0

Most likely your submodule repository has no revision that is referenced outer repository. And it may also be either not available at the remote specified for submodule, or you do not have remote set up for submodule. You can try to go into client/src/util and git fetch in there.

(why do you sudo it? if it belongs to root why aren't you not in root shell and if it doesn't, why do you change to root?)

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173