Back to Git & Dev Tools
2026-01-316 min read

Git subtree is a great alternative (Git & Dev Tools)

Learn Git subtree is a great alternative (Git & Dev Tools) step by step with clear examples and exercises.

Why This Matters

In software development, managing project dependencies is crucial for maintaining a clean and organized repository. Both Git Submodules and Git Subtree serve this purpose, but each has its strengths and weaknesses. Git Subtree offers a more straightforward approach with better performance and easier maintenance compared to Git Submodules.

Advantages of Using Git Subtree

  • Simplified dependency management: Git Subtree treats the subdirectory as part of your main repository, making it easier to manage and update dependencies compared to Git Submodules.
  • Better performance: Since Git Subtree only tracks changes within the subdirectory, it results in faster repository operations.
  • Reduced conflict resolution: With Git Subtree, you can merge branches or pull requests directly into your main repository, reducing the likelihood of conflicts compared to Git Submodules.

Prerequisites

To follow along with this tutorial, you should have a basic understanding of:

  • Git fundamentals (committing, branching, merging)
  • Navigating the command line
  • Familiarity with creating and managing repositories on platforms like GitHub or Bitbucket

Core Concept

Git Subtree enables you to include another repository as a subdirectory within your project. Unlike Git Submodules, it treats the subdirectory as part of your main repository, making it easier to manage and update dependencies.

Setting up Git Subtree

  1. Add the remote repository URL to your local repository's .git/config file:
[subtree]
dir=path/to/subdirectory
url=https://github.com/username/dependency-repo.git
  1. Initialize the subdirectory as a git subtree:
git subtree add --prefix=path/to/subdirectory <commit-hash>
  1. To update the subtree, simply pull changes from the remote repository:
git pull origin master

Merging and Branching

When working with Git Subtrees, you can merge branches or pull requests directly into your main repository, rather than managing them separately as you would with Git Submodules. This makes it easier to keep your dependencies up-to-date and avoid conflicts.

Creating a New Branch in the Subtree

  1. Create a new branch in the subtree:
git checkout -b subtree/new-branch origin/dependency-repo/new-branch
  1. Merge the new branch into your main repository:
git checkout master
git merge subtree/new-branch

Merging a Pull Request in the Subtree

  1. Fetch the remote repository's pull requests:
git fetch upstream pull/<pull-request-number>/head
  1. Create a new branch based on the pulled changes:
git checkout -b subtree/pull-request-<number> FETCH_HEAD
  1. Merge the new branch into your main repository:
git checkout master
git merge subtree/pull-request-<number>

Worked Example

Let's say you have a project that depends on a library called my-library. You can add my-library as a git subtree, update it, and merge changes using the following steps:

  1. Add the remote repository URL to your local repository's config file:
echo "url = https://github.com/username/my-library.git" >> .git/config
  1. Initialize the subdirectory as a git subtree:
git subtree add --prefix=lib my-library master
  1. To update the library, pull changes from the remote repository:
git pull origin master
  1. If you want to merge a specific branch or pull request, use the following commands:
  • Creating a new branch in the subtree:
git checkout -b subtree/new-branch origin/my-library/new-branch
git checkout master
git merge subtree/new-branch
  • Merging a pull request in the subtree:
git fetch upstream pull/<pull-request-number>/head
git checkout -b subtree/pull-request-<number> FETCH_HEAD
git checkout master
git merge subtree/pull-request-<number>

Common Mistakes

Forgetting to initialize the subdirectory as a git subtree

If you don't initialize the subdirectory as a git subtree, changes made within the subdirectory will not be tracked by Git.

Merging conflicts between the main repository and the subtree

When merging changes from the main repository and the subtree, conflicts may occur. Resolve these conflicts manually using standard Git merge strategies.

Handling Merge Conflicts

  1. Identify the conflicting files:
git status
  1. Open the conflicting files in a text editor and resolve the conflicts.
  1. Save and close the files.
  1. Stage the changes:
git add <conflicting-file>
  1. Commit the resolved conflicts:
git commit -m "Resolved merge conflict"

Merging a pull request into an outdated subtree branch

If you merge a pull request into a subtree branch that is outdated compared to the remote repository, Git will create a new commit in your main repository. To avoid this, always ensure your subtree branch is up-to-date before merging pull requests.

Updating the Subtree Branch Before Merging a Pull Request

  1. Fetch the remote repository's latest changes:
git fetch upstream
  1. Rebase your subtree branch onto the updated remote branch:
git rebase upstream/master subtree/subdirectory-branch
  1. If there are merge conflicts, resolve them as described in the "Handling Merge Conflicts" section.
  1. Once the rebase is complete, you can safely merge the pull request into your subtree branch:
git checkout subtree/subdirectory-branch
git merge upstream/pull-request-<number>

Practice Questions

  1. How can you update a git subtree in your project?
  • Pull changes from the remote repository and merge them into your main branch.
  1. What are the advantages of using Git Subtree over Git Submodules?
  • Simplified dependency management, better performance, reduced conflict resolution.
  1. If you encounter merge conflicts between the main repository and the subtree, how should they be resolved?
  • Identify the conflicting files, open them in a text editor, resolve the conflicts, save and close the files, stage the changes, commit the resolved conflicts.
  1. How can you add multiple subtrees to your repository?
  • Add multiple remote URLs and directories to the .git/config file and initialize each subdirectory as a git subtree using the git subtree add command.
  1. What is the best practice for updating a git subtree with new changes from the remote repository?
  • Pull changes from the remote repository, merge them into your main branch, and then merge the changes into the subtree using the git subtree merge command.
  1. How can you create a new branch in the subtree based on a specific commit hash?
  • Fetch the remote repository's commit and create a new branch in the subtree:
git fetch upstream <commit-hash>
git checkout -b subtree/new-branch FETCH_HEAD
  1. How can you remove a git subtree from your repository?
  • Remove the remote URL and directory from the .git/config file, then delete the subdirectory and commit the changes:
rm .git/config -e path/to/subdirectory
git add .git/config path/to/subdirectory
git commit -m "Removed git subtree"

FAQ

Q: Can I have multiple subtrees within a single repository?

A: Yes, you can add multiple subtrees to your repository by specifying different directories and remote URLs in the .git/config file.

Q: How do I remove a git subtree from my repository?

A: To remove a git subtree, use the following command:

git subtree prune --prefix=path/to/subdirectory origin/master

Q: Can I push changes made to a git subtree back to the remote repository?

A: No, you cannot directly push changes made to a git subtree back to the remote repository. Instead, you should pull changes from the remote repository and merge them into your main branch before pushing.

Pushing Changes to the Remote Repository

  1. Pull changes from the remote repository:
git pull origin master
  1. Merge the changes into your main branch:
git merge master
  1. Commit the merged changes:
git commit -m "Merged changes from remote repository"
  1. Push the committed changes to the remote repository:
git push origin master
Git subtree is a great alternative (Git & Dev Tools) | Git & Dev Tools | XQA Learn