Update a submodule to the latest commit
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
A Git submodule is not a floating pointer to a repository branch. It is a reference to one specific commit in another repository, recorded by the parent repository. Updating a submodule to "the latest commit" therefore means moving that pointer to a newer commit and then committing the pointer change in the parent repo.
How submodule updates actually work
When you clone a repository with a submodule, Git checks out the submodule in a detached HEAD state at the exact commit recorded by the parent project. That is why the submodule does not automatically move when new commits land upstream.
You can see the current state with:
That output shows the commit hash currently pinned by the parent repository.
Updating a submodule to the latest remote commit
If the submodule tracks a branch, the simplest command is:
This fetches the configured remote branch for that submodule and checks out the latest commit from that branch.
Then commit the updated pointer in the parent repository:
Without the parent commit, other developers will not get the new submodule revision when they pull.
Updating manually from inside the submodule
You can also enter the submodule and update it like a normal repository:
This approach is useful when you want to inspect the incoming changes, switch branches, or resolve conflicts before recording the new commit in the parent repository.
Configuring which branch --remote should follow
If git submodule update --remote does not move where you expect, check .gitmodules.
That branch entry tells Git which remote branch should be followed for remote updates. Without it, the behavior may not match your intent.
After editing .gitmodules, sync the configuration:
Detached HEAD is normal
Many developers think something is broken when they enter a submodule and see a detached HEAD. That is the default state for a submodule checked out at a specific commit. It only becomes a problem if you intend to make changes inside the submodule and forget to switch to a branch first.
For read-only consumption, detached HEAD is completely normal.
Updating all submodules
If the repository contains more than one submodule, use:
That updates every configured submodule recursively. It is convenient, but you should still review what changed before committing the parent repository.
Common Pitfalls
- Updating the submodule locally and forgetting to commit the new submodule pointer in the parent repo.
- Assuming
git pullin the parent repository automatically advances submodules to the latest upstream commit. - Working inside a detached
HEADand making commits you later struggle to reference. - Using
--remotewithout confirming which branch the submodule is configured to follow. - Updating several submodules at once without reviewing compatibility or running tests afterward.
Summary
- A submodule records a specific commit, not a moving branch tip.
- Use
git submodule update --remote path/to/submoduleto advance it to the latest configured remote commit. - You can also enter the submodule, fetch and pull manually, then commit the updated pointer in the parent repo.
- Detached
HEADinside a submodule is expected unless you are actively developing in it. - The parent repository must commit the new submodule revision so teammates get the update.

