DEV Community

Cover image for Configure Multi-Repository Git Submodules with Push via Git SSH & Pull via HTTPS in Github
L Djohari
L Djohari

Posted on

Configure Multi-Repository Git Submodules with Push via Git SSH & Pull via HTTPS in Github

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"

Enter fullscreen mode Exit fullscreen mode

If you use commit GPG Signing you can add below configs

git config user.signingkey <GPG_KEY_ID>
git config commit.gpgsign true
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Initialize submodules and its dependencies if any

git submodule update --init --recursive
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

If you use commit GPG Signing you can add below configs

git config user.signingkey <GPG_KEY_ID>
git config commit.gpgsign true
Enter fullscreen mode Exit fullscreen mode

Go back to project folder

cd ../..
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

If you use commit GPG Signing you can add below configs

git config user.signingkey <GPG_KEY_ID>
git config commit.gpgsign true
Enter fullscreen mode Exit fullscreen mode

Go back to project folder

cd ../..
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)