Data report"State of code review 2024" is now liveRead the full report

How to fetch git submodules

Greg Foster
Greg Foster
Graphite software engineer


Note

This guide explains this concept in vanilla Git. For Graphite documentation, see our CLI docs.


When managing complex projects with Git, a common pattern is to rely on submodules to maintain external dependencies or separate large projects into smaller, manageable repositories. Understanding how to fetch updates for these submodules is crucial for keeping your projects synchronized with the external dependencies. This guide will explain how to effectively fetch submodules in Git, ensuring you have the latest changes from external repositories included in your project.

Git submodules allow you to keep a Git repository as a subdirectory of another Git repository. This is an effective way to manage projects that depend on external libraries or other projects. A submodule is essentially a snapshot of another repository at a particular point in time.

When you clone a repository with submodules, the submodules themselves are not automatically cloned; instead, only the links to their respective repositories are. To fetch submodule content, you need to update them explicitly.

To fetch the latest commits for all submodules, you can use the following command:

Terminal
git submodule update --remote

This command tells Git to go into each submodule and fetch the latest commits from the branch that the submodule is tracking.

For projects with nested submodules (submodules within submodules), a recursive fetch ensures that all submodules, at every level, are updated.

To recursively fetch these submodules use the following command:

Terminal
git fetch --recurse-submodules

This command fetches all the new commits for the parent project and all submodules recursively.

To fetch and update the submodules to the latest commit available on their respective tracked branches, you can combine fetching with updating:

Terminal
git submodule update --remote --recursive

This command fetches the latest changes for each submodule and any nested submodules recursively, then updates your project to use the latest commits.

Suppose you are working on a project that depends on several libraries, each included as a submodule. To ensure these libraries are up to date with their remote versions, you would typically do the following after a regular fetch:

  1. Fetch changes in the main repository:

    Terminal
    git fetch origin
  2. Update all submodules:

    Terminal
    git submodule update --init --recursive

    This command initializes and updates every submodule and their submodules recursively based on the commits recorded in the parent project.

To automate the process of fetching submodules when pulling changes in the main repository, you can configure Git to always update submodules recursively upon pulling:

Terminal
git config --global submodule.recurse true

This setting ensures that every time you pull the main repository, Git also fetches and updates all submodules recursively.

  • Submodule path does not exist: This error occurs if you try to update submodules without initializing them. Always run git submodule init or ensure --init is included in your update command.
  • Detached HEAD state in submodules: Submodules are checked out at a specific commit. If you need to make changes within a submodule, you should first checkout a branch.

For further reading see the official Git documentation.

Stay unblocked. Ship faster.
Experience the new developer workflow - create, review, and merge code continuously. Get started with one command.
Learn more

Give your PR workflow
an upgrade today

Stack easier | Ship smaller | Review quicker

Or install our CLI.
Product Screenshot 1
Product Screenshot 2