Skip to main content

Git Submodules Guide

This guide explains how to manage dependent repositories (<submodule1> and <submodule2>) inside the main <project> repo using Git submodules.

1️⃣ Clone the Main Repo

git clone <main-repo-url>
cd <main-repo-folder>
  • Clones only the main repo. Submodules are not fetched yet.

2️⃣ Add Dependent Repos as Submodules

# Add first submodule repo
git submodule add <submodule1-repo-url> <submodule1-folder>

# Add second submodule repo
git submodule add <submodule2-repo-url> <submodule2-folder>
  • This creates .gitmodules automatically.
  • .gitmodules maps the submodule folder paths to the repo URLs.
Example .gitmodules content:
[submodule "<submodule1-folder>"]
    path = <submodule1-folder>
    url = <submodule1-repo-url>

[submodule "<submodule2-folder>"]
    path = <submodule2-folder>
    url = <submodule2-repo-url>

3️⃣ Commit Submodules in Main Repo

git add .gitmodules <submodule1-folder> <submodule2-folder>
git commit -m "Added submodules <submodule1> and <submodule2>"
git push origin main
  • This stores the submodule references (commit pointers) in the main repo.
  • Important: It does not include the actual submodule code in the main repo.

4️⃣ Workflow for Making Changes

A. Make changes in a submodule

# Go inside submodule folder
cd <submodule1-folder>

# Edit files
echo "update something" >> file.txt

# Stage, commit, and push changes to submodule repo
git add file.txt
git commit -m "Updated <submodule1> files"
git push origin main

B. Update the main repo pointer

cd ../   # go back to main repo folder

# Stage the submodule pointer change
git add <submodule1-folder>
git commit -m "Updated submodule pointer for <submodule1>"
git push origin main
✅ This ensures the main repo points to the latest commit in the submodule.

C. Make changes in the main repo

  • Edit files outside submodule folders as usual:
echo "new feature" >> README.md
git add README.md
git commit -m "Updated README"
git push origin main
  • Submodule references remain unchanged unless you explicitly update them.

5️⃣ Pulling Updates

A. Pull main repo updates

git pull origin main
  • Updates main repo content and submodule commit pointers (but not submodule content).

B. Pull submodule updates

# Update all submodules to the commits the main repo points to
git submodule update --init --recursive

# Or, update submodules to latest remote commits
git submodule update --remote --merge
  • --init --recursive → fetches submodules after a fresh clone.
  • --remote --merge → updates submodules to latest commits from their remote repos.

6️⃣ Fresh Clone with Submodules

To clone and have submodules ready automatically:
git clone <main-repo-url>
cd <main-repo-folder>
git submodule update --init --recursive
  • This populates <submodule1-folder> and <submodule2-folder> folders.

7️⃣ Optional: Setup Script

You can create a setup.sh for developers:
#!/bin/bash
git submodule update --init --recursive
Usage:
chmod +x setup.sh
./setup.sh

8️⃣ Key Notes

  1. Submodule commits are independent — changes inside submodules must be committed and pushed inside the submodule repo.
  2. Main repo only tracks submodule commit pointers.
  3. .gitmodules contains mapping info: submodule path → repo URL.
  4. Fresh clones require git submodule update --init --recursive to populate submodules.
  5. Use git submodule update --remote --merge to sync submodules with the latest remote commits.