Back to Git & Dev Tools
2026-05-097 min read

About Git subtree merges (Git & Dev Tools)

Learn About Git subtree merges (Git & Dev Tools) step by step with clear examples and exercises.

Title: Mastering Collaborative Development with Git Subtree Merges - A full guide (Git & Dev Tools)

Why This Matters

Git subtree merges are an indispensable tool for managing complex, multi-repository projects. They allow developers to maintain separate repositories for different parts of a project while keeping them synchronized, making collaboration easier and more efficient. In this lesson, we will delve deep into Git subtree merges, exploring their benefits, prerequisites, core concepts, worked examples, common mistakes, practice questions, and frequently asked questions. By the end of this tutorial, you'll have a solid understanding of how to use Git subtree merges effectively in your development workflow.

Prerequisites

Before diving into Git subtree merges, it is essential to have a good grasp of the following concepts:

  1. Basic Git commands: clone, add, commit, push, pull, branch, and merge
  2. Understanding Git branches and merging strategies (e.g., fast-forward merge)
  3. Familiarity with GitHub or other version control platforms
  4. Experience working on collaborative projects using Git
  5. Knowledge of creating and managing Git submodules
  6. Comfortable navigating the command line

Core Concept

Git subtree merges enable you to include a specific branch from one repository as a subdirectory in another repository. This is achieved by treating the remote branch as a Git submodule and merging it into your main project's working directory.

Here's a step-by-step guide on how to perform a Git subtree merge:

  1. Add the remote repository as a Git submodule in your main project:
git submodule add <remote_url> path/to/subdirectory
  1. Initialize the submodule:
cd path/to/subdirectory
git config core.sparsecheckout true
  1. Create a .gitmodules file in your main project's root directory to track the submodule:
[submodule "path/to/subdirectory"]
path = path/to/subdirectory
url = <remote_url>
  1. Add the submodule to your .gitignore file to prevent it from being accidentally committed as a whole:
path/to/subdirectory
  1. Commit and push the changes to your main project repository.
  2. To update the submodule, navigate to the subdirectory and pull changes from the remote branch:
cd path/to/subdirectory
git checkout <branch_name>
git pull origin <branch_name>
  1. Perform a Git subtree merge in your main project's working directory:
git subtree add --prefix=path/to/subdirectory <remote>/<branch>:<subdirectory_branch>
  1. Commit and push the changes to your main project repository.

Important Notes

  • Ensure that the branch you are merging exists in the remote repository before attempting a Git subtree merge.
  • If there are conflicts during the merge, they will need to be resolved manually.
  • It's recommended to regularly update your submodules to avoid outdated dependencies.

Worked Example

Let's consider a simple example where we have two repositories: main-project and submodule. The main-project contains the main application code, while the submodule contains a library that our application depends on.

  1. First, clone both repositories locally:
git clone <main_project_url> main-project
git clone <submodule_url> submodule
  1. Add the submodule to main-project as a Git submodule:
cd main-project
git submodule add ../submodule lib
  1. Initialize the submodule and create the .gitmodules file:
cd lib
git config core.sparsecheckout true
touch .gitmodules
  1. Add the following content to the .gitmodules file:
[submodule "."]
path = .
url = <submodule_url>
  1. Commit and push the changes to main-project:
cd ..
git add .gitmodules lib
git commit -m "Added submodule"
git push origin master
  1. Now, let's say we have a new version of our library in the submodule. To update the library in main-project, navigate to the lib directory and pull changes from the remote branch:
cd lib
git checkout <new_branch>
git pull origin <new_branch>
  1. Perform a Git subtree merge in main-project's working directory:
cd ../..
git subtree add --prefix=lib <submodule>/<new_branch>:master
  1. Commit and push the changes to main-project:
git add lib
git commit -m "Updated submodule"
git push origin master

Common Mistakes

  1. Forgetting to initialize the submodule with git config core.sparsecheckout true.
  2. Committing the entire submodule instead of a specific branch using git add ..
  3. Failing to update the .gitmodules file when adding or removing submodules.
  4. Not adding the submodule path to the .gitignore file.
  5. Performing a regular merge instead of a Git subtree merge (use git subtree add --prefix= /:).
  6. Ignoring conflicts during the Git subtree merge and not resolving them manually.
  7. Not regularly updating submodules to keep dependencies up-to-date.
  8. Committing changes to the main project before updating the submodule, causing potential conflicts.
  9. Merging branches that are not compatible or have conflicting changes.
  10. Failing to handle merge conflicts properly, leading to broken code or lost changes.

Practice Questions

  1. You have two repositories, main-project and submodule. How would you add the submodule as a Git submodule in the main-project?
  2. Suppose you have updated the library in your submodule. What steps would you follow to update the library in your main-project using Git subtree merges?
  3. Explain the purpose of the .gitmodules file and why it's important to include it when adding a submodule to your main project.
  4. What is the difference between a regular merge and a Git subtree merge, and when would you use each one?
  5. You encounter a conflict during a Git subtree merge. How would you resolve the conflict manually?
  6. When should you consider using Git subtree merges instead of including the library directly in your main project?
  7. What are some best practices for managing Git submodules and avoiding common mistakes?
  8. How can you handle merge conflicts between branches in different repositories during a Git subtree merge?
  9. What is the impact of committing changes to the main project before updating the submodule, and how can this be prevented?
  10. How would you handle a situation where the branch you want to merge no longer exists in the remote repository?

FAQ

  1. Why should I use Git subtree merges instead of including the library directly in my main project?
  • Git subtree merges allow for better collaboration and code organization, as different developers can work on separate repositories without affecting each other's work until they are ready to merge changes.
  1. Can I use Git subtree merges with private repositories or only public ones?
  • Yes, you can use Git subtree merges with both public and private repositories as long as you have the necessary permissions to access them.
  1. What happens if I try to merge a branch that has been deleted from the remote repository?
  • If the branch you're trying to merge no longer exists in the remote repository, Git will display an error message. You can either create a new branch with the same name or find an alternative approach to merging your changes.
  1. Can I use Git subtree merges with multiple submodules in my main project?
  • Yes, you can have multiple submodules in your main project and perform Git subtree merges for each one individually.
  1. What are some best practices when working with Git subtree merges?
  • Some best practices include regularly updating your submodules to avoid outdated dependencies, committing changes to the main project frequently, resolving conflicts during Git subtree merges promptly, and ensuring that the main project and its submodules are compatible before merging.
  1. How can I handle merge conflicts between branches in different repositories during a Git subtree merge?
  • To handle merge conflicts, you should resolve them manually by editing the files in question and committing the changes in both the main project and the submodule. Then, perform another Git subtree merge to ensure that all changes are properly synchronized.
  1. What is the impact of committing changes to the main project before updating the submodule, and how can this be prevented?
  • Committing changes to the main project before updating the submodule can lead to broken dependencies or incompatible code. To prevent this, it's best to update the submodule first and then commit changes to the main project.
  1. How would you handle a situation where the branch you want to merge no longer exists in the remote repository?
  • If the branch you want to merge no longer exists, you can either create a new branch with the same name or find an alternative approach to merging your changes (e.g., using a different branch or manually copying the required files).
  1. What are some common mistakes when working with Git subtree merges and how can they be avoided?
  • Common mistakes include forgetting to initialize the submodule, committing the entire submodule instead of a specific branch, failing to update the .gitmodules file, not adding the submodule path to the .gitignore file, performing regular merges instead of Git subtree merges, and ignoring conflicts during the merge. To avoid these mistakes, it's essential to follow best practices, such as regularly updating submodules, committing changes promptly, and resolving conflicts manually when necessary.
  1. What are some tools or plugins that can help with managing Git subtree merges more efficiently?
  • Several tools and plugins can help manage Git subtree merges more efficiently, including:
  • SubGit (): A tool for migrating a Git repository to a Mercurial repository while preserving the Git history.
  • Gerrit Code Review (): A web-based code review tool that integrates with Git and provides collaboration features for developers.
  • Sourcetree (): A graphical Git client for Windows, Mac, and Linux that simplifies the process of managing submodules and performing Git subtree merges.
About Git subtree merges (Git & Dev Tools) | Git & Dev Tools | XQA Learn