Subtrees allow splitting and merging histories between Git repositories. They're frequently used to support development in a monorepo whilst enabling components to be distributed independently of one another.

  • add always imports a copy of a history up the specified commit or reference, placing the files under the specified prefix, creating a merge commit to join the histories:
    • [--prefix <prefix>] <commit> imports a copy of the local history up to the specified commit.
    • add [--prefix <prefix>] <remote> <ref> imports the remote history up to the specified reference.
    • --squash can be used to flatten the history into a single commit.
  • merge [--prefix <prefix>] <commit> merges changes up to to the specified commit. Again, --squash can be used to flatten the history into a single commit. When --squash is used it's possible to go backwards to an older revision as well as forwards.
  • pull [--prefix <prefix>] <remote> <ref> does a fetch prior to a merge.
  • split [--prefix <prefix>] [<commit>] splits a new history from the history of the subtree at the specified prefix, including only changes that affect the prefix. The history of prefix will be at the root of the new project. Splitting the same history will always result in the same output.
  • push [--prefix <prefix>] <remote> <ref> performs a split from the surprised prefix, then pushes the result to the specified remote and reference.