bashadvanced

Git Subtree Workflow

Use git subtree to include external repositories as subdirectories without submodule complexity.

bash
# Add a remote for the sub-project
git remote add lib-remote https://github.com/org/lib.git

# Add subtree (imports full history)
git subtree add --prefix=vendor/lib lib-remote main --squash

# Pull latest changes from the sub-project
git subtree pull --prefix=vendor/lib lib-remote main --squash

# Push local changes back to the sub-project
git subtree push --prefix=vendor/lib lib-remote main

# Split subtree into its own branch (for extraction)
git subtree split --prefix=vendor/lib --branch=lib-split

# Then push the split to the sub-project repo
git push lib-remote lib-split:main

# Squash: collapses sub-project history into one commit
# Without --squash: preserves full commit history

# Subtree vs Submodule comparison:
# Subtree: code is part of your repo, no extra commands for clones
# Submodule: reference only, requires init/update after clone

# List all subtrees (no built-in command)
git log --oneline --grep="git-subtree-dir" | head

Use Cases

  • Including shared code without submodule complexity
  • Merging separate repos into a monorepo
  • Contributing upstream changes from a monorepo

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.