TL;DR: what you got is, I think, the case I mention below where you have not pushed the submodule commit. So now when the superproject goes to get the one specific commit out of the submodule the superproject has cloned, it (the superproject Git) cannot find it (the desired commit in the submodule).
Background
Submodules are a pain because there is an enormous tension between the fact that each submodule itself is a Git repository, and the fact that each "superproject" (controlling a submodule) insists that it knows which commit that the submodule must use.
This all works just fine when all of your submodules are external libraries that someone else maintains. You write some code that needs libraries A, B, and C. You test it with "commit 1234567
" from A, "commit 8888888
" from B, and "commit fedcba9
" from C, and it all works ... so you decree that this version of the code shall always and forever use those three commits from those three submodules.
You do this simply by making a commit in the superproject. Each commit records, for all time, exactly which commits the submodules must be on.
Then, whenever you check out the superproject, you tell your superproject Git to go meddle in each sub-repository and detach its HEAD. This is why you see "detached at" or "detached from". The "at" or "from" part is totally irrelevant at this point: pay no attention to it! This is meant for your information when you are working on those libraries, and because you're actually working on the superproject, your superproject Git assumes that you are not working on them.
But there's the rub: what if you want to work on them? Your superproject Git screams at you, No no no, you may not touch them! I control them! :-) Well, it's not quite that bad, but ... it's bad.
To work in a repository, you generally want to be on a branch. So you must go into the submodule and undo what your superproject Git did, by checking out some particular branch. Now you can work on the submodule in the normal fashion.
But this upsets your superproject Git. Moreover, you can't really test it until you have everything all lined up again. You must enter all the submodules, yank them back into "branch-y" mode, work in them, maybe test them individually, and maybe even make commits. Now you can go back to your superproject ... but you can't make commits there yet, because they're still remembering the old detached-HEAD hashes!
The only way to get everything all lined up again is to actually make the commits in the submodules. Now each submodule has a new hash ID, which each submodule's Git assigned when you made the commits there. You may now climb back up to your superproject and tell that Git: "I'm ready to commit, but before I do, here are your new hash IDs." You do this by git add
-ing each submodule again, which makes your superproject Git go and read out the submodule hashes and put them into your superproject's index. Now you can git commit
in the superproject, which permanently, forevermore, records the new commit as using the new hashes for each of the various submodules.
Note that if you now push the superproject, everyone else has a problem: the new commits you made in the submodules are in your submodule repositories, but those commits have not yet been pushed back to wherever they may go. Anyone who fetches your new superproject commit gets a commit that says "submodule A shall use commit feedcab
", but they can't get commit feedcab
until you push that too. So you must push all the submodules first, and only then push the superproject.
This does all work, but notice how brittle and fragile the process is. Git's submodules have gotten better over time, in that you can now actually tell the superproject controlling Git to (recursively) descend into each submodule Git and put that on a branch (whose branch name is recorded in the superproject). That takes care of the first problem.
If you're not the one who controls the submodule's remote repository, though, you get a different set of problems. The git submodule update
command has grown a whole raft of additional options to try to accommodate these cases as well. The git submodule foreach
command lets you run anything (such as your own scripts) in every submodule, which gives you complete control, at the expense of making you write, well, complete control. But the situation with submodules is still fairly messy, and many organizations try to avoid them (I would, and do, myself).