I have problems with submodules checking out locally. Here are my remotes:
origin [email protected]:myfork/fork.git (fetch)
origin [email protected]:myfork/fork.git (push)
main_repo [email protected]:some/path/main_repo.git (fetch)
main_repo [email protected]:some/path/main_repo.git (push)
The problem is that when trying to fetch 1 of the submodules, I get:
remote:
remote: ========================================================================
remote:
remote: The project you were looking for could not be found or you don't have permission to view it.
remote:
remote: ========================================================================
remote:
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
The submodule was added to the project using relative paths since our Gitlab CI runners requires it to be able to check them out. So I confirmed that the .gitmodules
file showed the correct path (../../path/submodule.git) and it is correct.
Upon inspection of .git/config
, I can see that this exact submodule does not have a correct path. What gives?
The problem is that relative submodules get their URL relative to the default remote.
As per git submodule man page:
If the URL is relative, it will be resolved using the default remote. If there is no default remote, the current repository will be assumed to be upstream.
In this case, origin
is a fork of the original repository and the project is stored in an entirely different location to the original repository.
Here are the different paths to take into account:
Original repository: some/path/main_repo.git
Fork: mynamespace/myfork/main_repo.git
Target submodule: some/submodule_path/submodule.git
Note the same parent (some/) for the original repository and the submodule, but not for the fork. This would work when the origin
remote is set to the original repository, but not when the fork is set as origin
! When the URL resolution for the submodule is based on the fork’s URL, this results in an incorrect path and fails to access the repository.
To solve the problem, rename the remotes so that origin
corresponds to the original repository on which the submodule’s relative path is based on:
git remote rename origin myfork
git remote rename main_repo origin
git submodule sync
Then the submodule should clone without issue.