LinuxCommandLibrary

git-subtree

Manage subprojects within a git repository

TLDR

Add a Git repository as a subtree and squash the commits together

$ git subtree add [[-P|--prefix]] [path/to/directory] --squash [repository_url] [branch_name]
copy

Update subtree repository to its latest commit
$ git subtree pull [[-P|--prefix]] [path/to/directory] [repository_url] [branch_name]
copy

Merge recent changes up to the latest subtree commit into the subtree
$ git subtree merge [[-P|--prefix]] [path/to/directory] --squash [repository_url] [branch_name]
copy

Push commits to a subtree repository
$ git subtree push [[-P|--prefix]] [path/to/directory] [repository_url] [branch_name]
copy

Extract a new project history from the history of a subtree
$ git subtree split [[-P|--prefix]] [path/to/directory] [repository_url] [[-b|--branch]] [branch_name]
copy

SYNOPSIS

git subtree <add|push|pull|merge|split> [--prefix=<prefix>] [--squash] <repo> [<ref>]

PARAMETERS

--prefix=
    Directory path for the subtree (required for most subcommands)

--squash
    Collapse subtree commits into a single commit

--squash-prefix=
    Prefix for squashed commits (default: same as --prefix)

--message=
    Custom commit message for add/pull/merge

--no-commit
    Stage changes without committing (add/pull/merge)

--no-prefix
    Omit prefix during split

-b / --branch=
    Branch for split output

-P
    Short form of --prefix

-m
    Short form of --message

-o
    Options passed to underlying git fetch/clone

DESCRIPTION

Git subtree is a contributed Git command for nesting one repository inside another as a subdirectory. It enables easy integration of external projects into your main repo while keeping them synchronized with upstream changes. Unlike git submodule, which uses pointers to external repos, subtree fully merges the history (optionally squashed) into your repo, avoiding detached HEAD issues and simplifying CI/CD.

Use cases include vendor branches, third-party libs without releases, or monorepos. Subcommands handle adding/pulling upstream updates, pushing local changes back, merging specific commits, and splitting subtrees for extraction. It relies on a custom merge strategy ("subtree"), preserving file paths during merges.

CAVEATS

Located in Git's contrib/ directory; manually install script to $PATH. History bloat possible without --squash. Not ideal for frequent/large updates vs. submodules. Split requires linear history.

SUBTREE STRATEGY

Uses Git's built-in "subtree" merge strategy; run git merge -s subtree manually if needed.

INSTALLATION

Copy git-subrepo/contrib/git-subtree/git-subtree to /usr/local/bin and chmod +x.

HISTORY

Created by Avery Pennarun in 2009 as git-subtree.sh for easier subtree management. Added to Git contrib/ in v1.7.11 (2011). Evolved with split/rejoin support; remains non-core porcelain.

SEE ALSO

Copied to clipboard