Git Move Subdirectory to New Repo

·
3 min read
notes
#git #filter-repo #subtree

Two methods to move subdirectory to new repo with full history - git filter-repo and git subtree split

TL;DR

Two ways to move a subdirectory to a new repository while preserving commit history:

  • git subtree split - Safe, non-destructive, built-in
  • git filter-repo - Powerful, requires installation, rewrites history

Why This Rocks

I was working on a monorepo and needed to split out a subdirectory into its own repository. Found two great methods - one safe and built-in, another more powerful but requires external tools.

Method 1: Git Subtree Split (Safe & Built-in)

This is the safer, non-destructive method using built-in Git commands.

Step 1: Create New Branch with Subdirectory

In your original repository:

Terminal window
git subtree split --prefix=<path/to/your/subdirectory> -b <new-branch-name>

For example, to split my-app into a branch called my-app-split:

Terminal window
git subtree split --prefix=my-app -b my-app-split

Step 2: Create New Remote Repository

Create a new empty repository on GitHub/GitLab and get its URL.

Step 3: Push Branch to New Repo

Terminal window
git push <new-repo-url> <new-branch-name>:main

Example:

Terminal window
git push https://github.com/user/new-app-repo.git my-app-split:main

Step 4: Clean Up

Remove the temporary branch from original repo:

Terminal window
git branch -D my-app-split

Method 2: Git Filter-Repo (Powerful & Clean)

This method rewrites history but gives cleaner results.

Step 1: Install git-filter-repo

Terminal window
pip install git-filter-repo

On macOS you can also use brew install git-filter-repo

Step 2: Clone Fresh Copy

Terminal window
git clone --mirror <original-repo-url> temp-repo
cd temp-repo

Step 3: Filter History

Terminal window
git filter-repo --path <path/to/your/subdirectory>

For example, if your subdirectory is my-app:

Terminal window
git filter-repo --path my-app/

Step 4: Create New Remote

Create a new empty repository on GitHub/GitLab and get its URL.

Step 5: Push Filtered History

Terminal window
git remote set-url origin <new-repo-url>
git push --mirror

That’s it! Your new repo now has only the subdirectory and its complete history.

Cleanup (Optional)

To remove the subdirectory from the original repo:

Terminal window
# In fresh clone of original repo
git filter-repo --invert-paths --path <path/to/your/subdirectory>
git push origin --force --all

Which Method to Choose?

Featuregit subtree splitgit filter-repo
SafetyNon-destructive - Creates new branch, leaves original untouched⚠️ Rewrites history - Must use on clone
InstallationBuilt-in - No extra tools neededRequires install - pip install git-filter-repo
ProcessCreates branch in existing repo, push to new remoteCreates new repo folder locally, then push
Best forQuick, safe splits without touching originalClean history and complex migrations

Bottom line: Use git subtree split for safe, simple splits. Use git filter-repo when you need the most powerful tool and plan to clean up the original repo too.

References