Next.js starter your AI actually understands. Ship internal tools in days not weeks. Pre-order $199 $499 → [Get it now]

How to subtree split in Git

Git subtree split extracts a subdirectory into a new branch containing only the commits that touched that path. As the creator of CoreUI with over 25 years of version control experience since 2000, I’ve used subtree split to extract reusable libraries from monorepos without losing history. The standard approach runs git subtree split --prefix to create a new branch, then optionally pushes it to a separate repository. This preserves the complete commit history of the extracted code.

Split a subdirectory into a new branch with its full history.

git subtree split --prefix=src/utils -b utils-library

The --prefix specifies which directory to extract. The -b creates a new branch containing only commits that modified files in that directory. The branch has a clean history as if the library always lived in its own repo.

Pushing Split Branch to New Repository

Publish the extracted code as a standalone repository.

# Create the split branch
git subtree split --prefix=src/utils -b utils-library

# Add remote for the new repository
git remote add utils-repo https://github.com/username/utils.git

# Push the split branch as main
git push utils-repo utils-library:main

The split branch maps onto the new repository’s main branch. All commits from the subdirectory appear in the new repo with their original messages and timestamps. Contributors keep their attribution.

Splitting with a Squash

Create a clean single commit instead of full history.

git subtree split --prefix=src/utils --squash -b utils-clean
git push utils-repo utils-clean:main

The --squash condenses all history into one commit. Use this when the full history is noisy or contains sensitive information. The new repository starts fresh from a single snapshot.

Verifying the Split

Check the extracted branch before pushing.

# Switch to the split branch
git checkout utils-library

# Verify only expected files are present
ls -la

# Check commit history
git log --oneline

# Count commits
git rev-list --count HEAD

# Switch back to main
git checkout main

Review the file structure and history before pushing. The directory should be the repository root. Only commits touching the original subdirectory should appear.

Automating Regular Splits

Keep a split repository synchronized.

# Initial split
git subtree split --prefix=src/utils -b utils-library
git push utils-repo utils-library:main

# After new commits to src/utils
git subtree split --prefix=src/utils -b utils-library
git push utils-repo utils-library:main

Running subtree split again on an existing branch is safe. Git detects which commits are new and appends only those. Push updates the external repository incrementally.

Best Practice Note

This is the same subtree split workflow we use when extracting shared utilities from CoreUI into standalone packages. Subtree split is the cleanest way to share code from a monorepo. The key advantage over copying files is the preserved history - git blame still works correctly. After splitting, decide whether to continue development in the monorepo and sync periodically, or move to the standalone repository permanently. For ongoing projects, add the split-and-push as a CI/CD step to keep external repositories up-to-date automatically.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to set focus on an input field after rendering in React
How to set focus on an input field after rendering in React

How to get element ID in JavaScript
How to get element ID in JavaScript

How to Convert a Map to an Array in JavaScript
How to Convert a Map to an Array in JavaScript

How to validate an email address in JavaScript
How to validate an email address in JavaScript

Answers by CoreUI Core Team