Skip to content

Git Submodules Workflow

Terminal window
cd parent-repo
git submodule add https://github.com/username/child-repo.git path/to/child-repo
git submodule update --init --recursive

Option B — Add a local repo as a submodule (no remote)

Section titled “Option B — Add a local repo as a submodule (no remote)”
Terminal window
git submodule add ../child-repo path/to/child-repo
git submodule update --init --recursive
Terminal window
cd path/to/child-repo
git status
git add .
git commit -m "Your descriptive message"

If a remote exists:

Terminal window
git push origin main

Once you’ve committed inside the submodule:

Terminal window
cd ../.. # back to parent repo
git status # shows "modified: path/to/child-repo"
git add path/to/child-repo
git commit -m "Update submodule to latest commit"
git push origin main

When cloning a parent that includes submodules:

Terminal window
git clone --recurse-submodules https://github.com/username/parent-repo.git

If you’ve already cloned without initializing:

Terminal window
git submodule update --init --recursive

To pull new commits from all submodules:

Terminal window
git submodule update --remote --merge
ActionCommand
Re-sync submodule URLs after changing remotesgit submodule sync
Remove a submodule cleanlygit submodule deinit -f path/to/submodule && rm -rf .git/modules/path/to/submodule && git rm -f path/to/submodule
Check current submodule commitsgit submodule status
Update all submodules recursivelygit submodule update --remote --recursive
Terminal window
parent-repo/
├── .git/
├── .gitmodules
├── path/
└── child-repo/
├── .git/ # submodule’s repo files
└── ...

Example .gitmodules file:

[submodule "path/to/child-repo"]
path = path/to/child-repo
url = https://github.com/username/child-repo.git
  1. You commit changes inside the submodule.
  2. The submodule HEAD changes (new commit).
  3. The parent repo detects this and records the new commit hash.
  4. You commit that change in the parent.
  5. Each repo can be pushed independently.
TaskLocationCommand
Add submoduleParentgit submodule add <url> path/to/child
Commit changesSubmodulegit add . && git commit -m "msg"
Push submoduleSubmodulegit push origin main
Update pointerParentgit add path/to/child && git commit -m "msg"
Push parentParentgit push origin main
Clone allgit clone --recurse-submodules <url>
Update allgit submodule update --remote --recursive