Why does git fail to fetch specific valid submodule for a given commit and how to fix it?
Asked Answered
K

10

86

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 as in I can use to access that commit through the web interface.

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.

Kentkenta answered 23/2, 2017 at 13:36 Comment(10)
The given commit hash is a valid one. Do you mean that the commit with that hash is present in the submodule repo?Selah
Yes, I can follow the link in my web browser (using GitLab) to the page that displays all the changes that happened with that commit so it's not like someone did some sort of a reset.Kentkenta
It may be a permission problem. Can you clone just the submodule repo?Selah
Yes, without a problem.Kentkenta
Is there anything special in the .gitmodules file for that submodule?Selah
I don't think so. Will post the contents. Sorry for not doing that earlier.Kentkenta
Just one clarification - is the filename .gitmodules or .gitsubmodules?Selah
It's .gitmodules.Kentkenta
Possible explanation: "available in browser page" does not mean it's still reachable from a reference. Cloning a repository will only bring in commits reachable from references (and if you clone with --shallow or --single-branch, that limits the commits further). If the desired commit is not brought in, Git will not be able to check it out.Wirer
Does the problematic commit in the submodule belong to any current branch? Or it once belonged to a branch that was recently rebased?Selah
L
53

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
Lycanthropy answered 23/2, 2017 at 20:29 Comment(6)
I have the same problem. The submodule is tracking a branch. I can see the branch on bitbucket and when I clone the submodule individually. But when the main project is cloned the submodule branch is no longer listedYahweh
@Yahweh Is it listed after a git fetch and git branch -avv done inside the submodule folder?Lycanthropy
The problem was the repos were moved from Gitlab to Bitbucket. The new branch was created in Bitbucket and the .gitmodules were never updated on the main projectYahweh
@Yahweh OK. Could you describe that in a separate question? That will be easier to review than here, buried in comments.Lycanthropy
As per @Sycophant comment to @Alim answer, the - - remote switch was the key for me. This worked for me git submodule update --init --recursive --remoteSeabolt
@Seabolt Thank you for that feedback. I have included your comment in the answer for more visibility.Lycanthropy
O
114

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.

Overgrow answered 16/6, 2019 at 17:51 Comment(3)
After two months, we moved to monorepo.Overgrow
Thank you! The --remote option does the trick, because it fetches from the latest remote instead from gits old memory. So If you change the URL of a submodule then you have to use git submodule update --remoteSycophant
Switched repositories from gitlab to github with depending submodule repositories - this worked fine for me - big thanks!Belkisbelknap
L
53

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
Lycanthropy answered 23/2, 2017 at 20:29 Comment(6)
I have the same problem. The submodule is tracking a branch. I can see the branch on bitbucket and when I clone the submodule individually. But when the main project is cloned the submodule branch is no longer listedYahweh
@Yahweh Is it listed after a git fetch and git branch -avv done inside the submodule folder?Lycanthropy
The problem was the repos were moved from Gitlab to Bitbucket. The new branch was created in Bitbucket and the .gitmodules were never updated on the main projectYahweh
@Yahweh OK. Could you describe that in a separate question? That will be easier to review than here, buried in comments.Lycanthropy
As per @Sycophant comment to @Alim answer, the - - remote switch was the key for me. This worked for me git submodule update --init --recursive --remoteSeabolt
@Seabolt Thank you for that feedback. I have included your comment in the answer for more visibility.Lycanthropy
P
8

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:

  1. Checking that the url was the right one in the .gitmodules file
  2. Calling git submodule sync
  3. Calling git -C path/to/submodule fetch (if the submodule was already initialized)
  4. Calling git submodule update --init [--recursive] path/to/submodule (if the submodule has been deinit)
Pyrochemical answered 5/6, 2020 at 14:15 Comment(0)
T
5

I do not know what the exact problem was but below worked for me: (4th step is the key I think)

  1. git submodule update --init --recursive
  2. git pull --rebase --recurse-submodules
  3. git submodule update --force --recursive --init --remote
  4. git submodule sync
  5. git submodule update --init --recursive
Theorem answered 7/4, 2021 at 13:47 Comment(0)
L
3

The problem for me was that the submodule was pointing to a personal (clone of a) repository hosted on github.

I had multiple host repositories containing a reference to the same submodule. I had changed the HEAD of the submodule in one of those repositories and committed the repository. Unfortunately I had neglected to push the new submodule HEAD to github, so other instances of the repository didn't have a record of the latest head, even after git submodule update etc.

Lurette answered 5/4, 2019 at 12:24 Comment(0)
A
2

I started experiencing this intermittently in a (github-hosted) repo since February 2022. Possibly due to working in multiple worktrees on the same local git repository. I never configure or edit submodules, URLs or credentials. None of the submodule sync/--init solutions helped.

Eventually I found this to always fix submodule X:

  1. Remove the checkout directory X itself (assuming you don't have any changes in it!).

  2. Fix the corresponding plumbing directory, which is either

    • .git/modules/X (normally), or
    • .git/worktrees/worktree-name/modules/X (if you're in an additional worktree you created):

    either by deleting it entirely (upon which the next step will download most of it again), or by only deleting:

    • shallow and
    • refs/remotes/origin (or just the files in this directory)
  3. Restore everything with git submodule update X

Abigailabigale answered 16/12, 2021 at 11:15 Comment(0)
A
2

I ended up just going:

  1. Going into the submodules repo
  2. git pull for latest
  3. Going into the top repo root directory
  4. git commmit -m "updated submodule" so the main repo is made aware.
  5. git push

After that my problems all disappeared. This also fixed my Netlify problems.

Astronaut answered 22/2, 2022 at 15:1 Comment(1)
This probably isn't the best solution in that it resolves the mismatch by making it the expected state. It could cause issues for others who may be using using your repo. However, if it is your private repo and you're the only user, it definitely gets the job done quickly when the other solutions aren't working, hence my upvote. Thank you!Wendelina
L
0

In my case, git config for the submodules has been updated into ssh. I updated the parent project's git config as well as its submodules to http.

Aside from that, I updated my git credentials using window's web credentials which you can search in windows settings.

Manage Web Credentials in Windows

Lilith answered 13/9, 2021 at 10:27 Comment(0)
U
0

When I experienced this error, it was caused by the submodule reference pointing to a commit that only existed locally.

Ungraceful answered 28/10, 2021 at 16:7 Comment(0)
H
-3

Below command solved the problem

  • git submodule sync
Hatti answered 24/6, 2021 at 7:17 Comment(1)
This was already suggested in the above answers.Whensoever

© 2022 - 2024 — McMap. All rights reserved.