I had some trouble dealing with submodules. This is what I experienced, learned, and did to solve the issue.
Using a custom SSH URL
Let's see if our repository has submodules:
$ git submodule
9d83ae91cffb5840a5ff722e9f1dabc2d74c96ae vagrant/cookbooks (9d83ae9)
Yes, it does. Take a look at the submodule details which are stored in
.gitmodules
; it should look like this:
[submodule "vagrant/cookbooks"]
path = vagrant/cookbooks
url = git@github.com:AcmeCorporation/FlagshipProduct-cookbooks.git
Unfortunately, that's not the URL we want to use but instead we have a
dedicated alias in ~/.ssh/config
:
Host github
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_github
But first, initialize the submodule (this has to be done from the repository's root path):
$ git submodule init
Submodule 'vagrant/cookbooks' (git@github.com:AcmeCorporation/FlagshipProduct-cookbooks.git) registered for path 'vagrant/cookbooks'
Make sure that there is an URL shown between the parentheses; if there isn't, something is already wrong.
That step should have added a section to .git/config
:
[…]
[submodule "vagrant/cookbooks"]
url = git@github.com:AcmeCorporation/FlagshipProduct-cookbooks.git
If we would have tried to update the submodule with the original SSH URL, this might fail:
$ git submodule update
Permission denied (publickey).
fatal: The remote end hung up unexpectedly
Unable to fetch in submodule path 'vagrant/cookbooks'
Just adjust the SSH URL in .git/config
as necessary (in our case, use
above SSH host alias):
[…]
[submodule "vagrant/cookbooks"]
url = github:AcmeCorporation/FlagshipProduct-cookbooks.git
Now we can finally update the submodule:
$ git submodule update
Cloning into 'vagrant/cookbooks'...
remote: Counting objects: 302, done.
remote: Compressing objects: 100% (216/216), done.
remote: Total 302 (delta 86), reused 273 (delta 59)
Receiving objects: 100% (302/302), 149.71 KiB | 198 KiB/s, done.
Resolving deltas: 100% (86/86), done.
Submodule path 'vagrant/cookbooks': checked out '9d83ae91cffb5840a5ff722e9f1dabc2d74c96ae'
Yay! :)
Troubleshooting
This happened to me after I initialized the submodule:
$ git submodule update
fatal: Needed a single revision
Unable to find current revision in submodule path 'vagrant/cookbooks'
This is the sign that the initial checkout […] went completely wrong (I don’t know what makes this happen). Chances are that the directory exists, but is empty. Git does not seem to be able to overcome this situation, […]
So just delete the submodule's directory:
$ rm -rf vagrant/cookbooks
As pointed out in a comment to an answer on Stack Overflow, this might not be sufficient, so delete Git's internal related directory, too:
$ rm -rf .git/modules/vagrant/cookbooks
Now start again by initializing or updating the submodule.