Managing multiple repositories in Git, especially when using submodules, can be tricky—especially when you want different access levels for different users.
This article walks you through how to configure a Git multi-repository setup with submodules, ensuring that some users can have read-only access to the submodules via HTTPS, while your teams with correct credentials using git SSH can push changes via SSH.
Scenario Overview
Imagine you have a main repository (project) with two submodules (core and server).
project #(https://github.com/<your-git-user>/project)
libs/core #(https://github.com/<your-git-user>/core)
libs/server #(https://github.com/<your-git-user>/server)
Note: This workflow scenario only working if your repository and its submodules is public repository.
The goal is:
- Public users: Can clone the repository and its submodules via HTTPS (read-only access).
- Authorized users: Can push changes to submodules via SSH, while not affecting public access.
- This workflow is also apply to other git service provider such as gitlab or bitbucket.
- With this workflow, everyone in your team could have different SSH Key Aliases and will not impacted git repository configurations.
Through this tutorial we are use git SSH Aliases for managing multi-account git SSH, if you still figure it you can read quick article Configure Git with Multi-Account SSH and Verified Commits Using GPG in Github in here.
Steps to Add Submodules to Main Repository (project)
1. Clone your Main Repository using Git SSH
Make sure you have configured your git SSH Key Aliases in your workstation and add SSH Key to your github account.
git clone git@github.com-<your-git-user>:<your-git-user>/project.git
2. Configure Local Git Repository Config
Configure local repository config from inside the local main repository folder (project)
cd project
git config user.name "Your Name"
git config user.email "your_email@example.com"
If you use commit GPG Signing you can add below configs
git config user.signingkey <GPG_KEY_ID>
git config commit.gpgsign true
3. Add submodules to your Main Repository using HTTPS
git submodule add https://github.com/<your-git-user>/core.git libs/core
git submodule add https://github.com/<your-git-user>/server.git libs/server
Initialize submodules and its dependencies if any
git submodule update --init --recursive
We are halfway to finished this configuration, now we have to configure the push origin to use git SSH url for each submodule, users with Authorized git SSH Key can push changes to submodules.
Steps to Configure push origin Url for git Submodule Push Access
1. Get Current pull and push Origin Url From Submodules
For authorized users with SSH access, set the push origin for each submodule to use SSH. This ensures that pushes to submodules are done via SSH, while clones remain accessible via HTTPS.
git submodule foreach 'git remote -v
output
$ git submodule foreach 'git remote -v'
Entering 'libs/core'
origin https://github.com/<your-git-user>/core.git (fetch)
origin https://github.com/<your-git-user>/core.git (push)
Entering 'libs/server'
origin https://github.com/<your-git-user>/server.git (fetch)
origin https://github.com/<your-git-user>/server.git (push)
It will print your pull and push url, we will configuring push url to use git SSH url.
2. Configure Submodules for Push Access (SSH)
For each submodule (core, server) we have to configure push origin url
A. Configure Submodule libs/core Push Url
Go to submodule libs/core from project folder
cd libs/core
Change push url to core git SSH url
git remote set-url --push origin git@github.com-<your-git-user>:<your-git-user>/core.git
Configure git username, email and commit GPG signing from inside libs/core folder
git config user.name "Your Name"
git config user.email "your_email@example.com"
If you use commit GPG Signing you can add below configs
git config user.signingkey <GPG_KEY_ID>
git config commit.gpgsign true
Go back to project folder
cd ../..
Now your submodule libs/core will have push origin point to git SSH url.
B. Configure Submodule libs/server Push Url
Go to submodule libs/server from project folder
cd libs/server
Change push url to server git SSH url
git remote set-url --push origin git@github.com-<your-git-user>:<your-git-user>/server.git
Configure git username, email and commit GPG signing from inside libs/server folder
git config user.name "Your Name"
git config user.email "your_email@example.com"
If you use commit GPG Signing you can add below configs
git config user.signingkey <GPG_KEY_ID>
git config commit.gpgsign true
Go back to project folder
cd ../..
Now your submodule libs/server will have push origin point to git SSH url.
2. Verified if push origin url is Using Correct git SSH Url
In project folder execute
git submodule foreach 'git remote -v'
It will print your submodules push origin url to point to git SSH url.
$ git submodule foreach 'git remote -v'
Entering 'libs/core'
origin https://github.com/<your-git-user>/core.git (fetch)
origin git@github.com-<your-git-user>:<your-git-user>/core.git (push)
Entering 'libs/server'
origin https://github.com/<your-git-user>/server.git (fetch)
origin git@github.com-<your-git-user>:<your-git-user>/server.git (push)
The .gitmodules file should still use HTTPS URLs for cloning. This way, public users can easily clone the repositories:
[submodule "core"]
path = core
url = https://github.com/<your-git-user>/core.git
[submodule "server"]
path = server
url = https://github.com/<your-git-user>/server.git
3. Push Changes from the Main Repository
After making changes to the main repository or it submodules, push everything as usual when we do push.
Conclusion
Read-Only Access for Public Users
Users who do not have SSH credentials can still clone the repository and submodules via HTTPS, but they won't be able to push any changes.
They must push changes via Pull Request.
Write Access for Authorized Users
Authorized users with SSH keys configured in GitHub can push changes directly to the submodules via SSH, while other users retain read-only access via HTTPS.
Working & Push Changes to Submodules from Main Repository
With this workflow, you can focus working inside Main Repository (project) to made necessary changes and push changes without struggling.
Boost Productivity with GitLens
This is not paid sponsor, but I found from my experience during development GitLens extension for Visual Studio Code helps a lot for my use cases.
GitLens for Visual Studio Code simplifies managing multi-repos with submodules. It helps you:
- Track Submodule Changes: View commit history and differences across both the main repos and submodules.
- Easily Manage Configurations: Visualize and manage SSH/HTTPS URLs for cloning and pushing right in your editor.
GitLens turns your Git workflow into a seamless, visual experience—perfect for managing submodules across multiple repositories.
Top comments (0)