How to Use Git Submodules

Updated on 12 June, 2025
Learn to manage Git submodules effectively. Add, clone, update, and sync submodules with practical commands and tips to avoid common pitfalls in your projects.
How to Use Git Submodules header image

Git submodules let you embed one Git repository inside another. They're useful for managing shared libraries, vendor code, or reusable components across multiple projects without duplicating files. Each submodule links to a specific commit of an external repo, keeping its history and configuration separate from the parent project.

This article explains how to add, clone, update, and manage Git submodules effectively, with practical commands and tips to avoid common pitfalls.

The Short Answer Version

# Add a submodule to your repository
$ git submodule add https://github.com/user/repo.git path/to/submodule

# Initialize submodules in a cloned repository
$ git submodule init

# Update submodules to fetch content
$ git submodule update

# Clone repository and its submodules in one step
$ git clone --recurse-submodules https://github.com/user/project.git

# Pull latest commits from submodule’s remote
$ git submodule update --remote

# Remove a submodule completely
$ git submodule deinit -f path/to/submodule
$ rm -rf path/to/submodule
$ git rm path/to/submodule
$ rm .gitmodules

Add a Git Submodule

Submodules let you link another Git repository into your project while keeping its history and configuration separate. This section demonstrates how to add a submodule to an initialized Git project.

Command Syntax

To add a submodule:

git submodule add <submodule-url> <path>
  • <submodule-url>: The remote URL of the Git repository you want to add.
  • <path>: The target folder path inside your project where the submodule will live.
  • Git stores this reference in a .gitmodules file and treats the submodule as a pointer to a specific commit.

Command Demonstration

  1. Create a project directory.

    console
    $ mkdir my-project && cd my-project
    
  2. Initialize the directory as a Git repository.

    console
    $ git init
    
  3. Add a submodule.

    console
    $ git submodule add https://github.com/example/repo.git vendor/example-lib
    

    This clones the external repository into the vendor/example-lib folder and creates a .gitmodules file.

  4. Review .gitmodules.

    console
    $ cat .gitmodules
    

    Output.

    [submodule "vendor/example-lib"]
        path = vendor/example-lib
        url = https://github.com/example/repo.git
  5. Stage the .gitmodules file and submodule directory.

    console
    $ git add .gitmodules vendor/example-lib
    
  6. Commit the submodule addition.

    console
    $ git commit -m "Add example-lib as submodule"
    
  7. Push your committed changes to the remote repository.

    console
    $ git push origin main
    

Clone a Repository with a Git Submodule

When you clone a repository that includes submodules, Git does not fetch submodule content automatically unless explicitly instructed. This section explains how to initialize and update submodules correctly.

Command Syntax

  • To manually initialize and update submodules after cloning:

    git clone <repo-url>
    cd <repo-name>
    git submodule init
    git submodule update
  • To clone the repository and submodules in a single command:

    git clone --recurse-submodules <repo-url>
    • --recurse-submodules: Automatically clones and initializes all submodules during the initial clone.
    • git submodule init: Registers submodules from .gitmodules.
    • git submodule update: Fetches the submodule contents.
  • To update submodules to their latest remote-tracked commits:

    git submodule update --remote
    • --remote: Pulls the latest commit from the remote branch tracked by the submodule.

Command Demonstration

  1. Clone the main repository.

    console
    $ git clone https://github.com/example/project.git
    
  2. Change into the project directory.

    console
    $ cd project
    
  3. Initialize the submodules from .gitmodules.

    console
    $ git submodule init
    
  4. Download the contents of each submodule.

    console
    $ git submodule update
    
  5. (Alternative) Clone the repository and submodules in one step.

    console
    $ git clone --recurse-submodules https://github.com/example/project.git
    
  6. (Optional) Update submodules to the latest remote commit.

    console
    $ git submodule update --remote
    

By default, submodules track a specific commit. Use --remote only if you want to sync to the latest upstream commit on the tracked branch.

Precautions for Adding a Git Submodule

Before using submodules in a project, keep the following in mind:

  • Submodules track commits, not branches.

    By default, submodules point to a specific commit. They do not automatically follow the latest changes in the remote repository. You must manually update them with git submodule update --remote.

  • You must commit submodule updates explicitly.

    If you update a submodule to point to a new commit, the parent repository treats that as a change. You need to stage and commit the submodule pointer update.

  • Cloning with submodules requires extra steps.

    Users must remember to run git submodule init and git submodule update, or use the --recurse-submodules flag during cloning.

  • Submodules complicate pull/merge workflows.

    If different branches reference different submodule commits, merges or rebases can get messy. Always coordinate submodule usage in collaborative workflows.

  • CI/CD pipelines need submodule awareness.

    Ensure any automated build or deployment tools include logic to fetch and update submodules. A common failure point is forgetting --recurse-submodules.

Use submodules only when you truly need independent versioning of external codebases. Otherwise, simpler solutions like package managers or monorepo structures may be easier to maintain.

Conclusion

In this article, you learned how to use Git submodules to manage reusable code across projects. You added submodules to a repository, cloned projects with submodules, updated them to track remote changes, and removed them cleanly when no longer needed. By using submodules effectively, you maintained modular project structures, avoided code duplication, and ensured version consistency across dependencies.

Tags:

Comments

No comments yet.