Why does git fail to fetch specific valid submodule for a given commit and how to fix it?
I have a git
repo which has another one as a submodule
dependency. In the root of my project (where the .git
, .gitsubmodules
etc. are) I called
git submodule update
This failed with the following message:
Fetched in submodule path 'src/framework', but it did not contain cc8c38e9d853491c672452d8dbced4666fc73ec8. Direct fetching of that commit failed.
where src/framework
is a sub-directory of my project (PROJECT_ROOT/src/framework
) and should be where the third-party repo lands. The given commit hash is a valid one.
I have also tried git clone --recursive <my-repo>
but it fails too.
The contents of my .gitmodules
is
[submodule "src/framework"]
path = src/framework
url = [email protected]:gh/framework.git
In addition to that I have to note the following important fact: due to recent updates in the framework
repo my code breaks hence I really need to retrieve that specific version of it where things were working fine.
Solution 1:
Running this command after cloning (and receiving the error) solved my problem:
git submodule update --force --recursive --init --remote
Of course this is not a good solution. It is better to find and solve the underlying problem, but if anyone is in hurry, this was worked for me.
Solution 2:
Yes, I can follow the link in my web browser (using GitLab)
Can you clone that repo though, with that commit included?
GitLab has permission level which will restrict access, so make sure your git clone commands are executed with the right user, and with the ssh keys in said user home directory/.ssh
.
If you cannot clone the submodule repo yourself (in any place on your local hard drive), that would explain the error message.
The problem came from someone who has done a reset of the head to a commit prior to the one that was linked as a submodule in the repository I was working with. This rendered the reference invalid. I have no idea how to fix this
You can make sure the submodule follows a branch (here, for instance, master
):
cd /path/to/parent/repo
git config -f .gitmodules submodule.bar1.branch master
Then update the submodule at the last fetched commit master
git submodule update --remote
The --remote
option ensures that it will not use the superproject’s recorded SHA-1 to update the submodule, but will use the status of the submodule’s remote-tracking branch instead.
That would avoid the "did not contain cc8c38e9d853491c672452d8dbced4666fc73ec8
" error message.
drlolly adds in the comments:
The
--remote
switch was the key for me.
This worked for me:git submodule update --init --recursive --remote
Solution 3:
My case was that the url of the submodule had changed and it was de-synchronized with the parent repo. We noticed we could clone the parent and the child would initialize without fail, but this particular instance of the repository was failing.
Fixed it by:
- Checking that the url was the right one in the
.gitmodules
file - Calling
git submodule sync
- Calling
git -C path/to/submodule fetch
(if the submodule was already initialized) - Calling
git submodule update --init [--recursive] path/to/submodule
(if the submodule has been deinit)