Splitting Your Git Repo While Maintaining Commit History

Amanda Walker Brubaker
5 min readFeb 26, 2021
GitHub Logo with Background — Source

So you have multiple directories in your repo and you want to split that repo into multiple ones? In my case, I had a single repo that contained both my frontend JavaScript directory and my backend Ruby on Rails directory that I wanted to split into two so I could host them on Netlify and Heroku.

How to Split your Repo:

1. Check you are in the root directory of your repo.

Once you have cd’ed into the root directory, run a quick ls terminal command to ensure all the sub-directories are listed.

My ‘ls’ command lists the above sub-directories

While this isn’t necessary to split your repo, a fun way to check your repo’s git history is to run git log or git log --onelist |wc if you want to see how many commits that branch of the repo has (it’s the first number listed).

2. Check you are in the master branch

This is assuming you want to split the master branch. If not, make sure you are in the right branch.

Write git branch in your terminal to ensure you’re in the master branch.

3. Exit the Root directory

From the root directory, cd .. back one level until you are one level above the root directory.

4. Move your Original Repo Clone to a New Directory

In your terminal type mv mv [your root directory]/ [your root directory].orig. We do this because we are about to re-write the history of your repo.

Here’s what that previous two steps would look like for my repo where the original was called “bookclub-full-app”

Moving my repo clone to a new directory

If you check out your files on your computer, you’ll see that this repo has changed it’s name locally. On a mac this is in ‘Finder’

5. Create a New Clone of your Repo

Ensure you are on level above your newly renamed directory (hint: if you haven’t cd’ed anywhere, you should already be there!).

Clone your repo again: using git clone [insert repo url here]

Double check you have both repos by doing a quick ls check and ensuring both are listed. In my case I would have bookclub-full-app and bookclub-full-app.orig.

6. Decide Which Directory You Want to Split.

cd into your newly cloned repo (not the .orig). You should be back to the root directory where you’ll see a list of all your files and directories within your repo. In my case I have the same three subdirectories listed:

My ‘ls’ command lists the above directories and files

Once you ensure you’re in the root directory, do the following command:

git filter-branch --prune-empty --subdirectory-filter [name of subdirectory you want to create a new repo for] -- master

In my case it looked like this to get just my backend:

Splitting my backend subdirectory from the root directory.

filter-branch is the main git command to split your subdirectory from the root.

subdirectory-filter is what we use to say which subdirectory we want to split, so you write your subdirectory name directly after this.

— master at the end shows what commit we want to operate this on.

At the end, this will rewrite the history. You may get a notification about a gut of gotchas, just wait and it will complete after a few seconds.

7. Ensure you have Properly Re-written the Sub-directory and its History

If you type ls now, instead of seeing the original subdirectories, you’ll have a list of the subdirectories of your filtered branch.

We went from this to this:

Comparison of sub-directories pre-and-post-split.

As you can see, your new root directory contains all the files you want in it’s own repo. You can test this out by typing git log to ensure it has all the git history has been preserved.

8. Remove the Remote Reference to the Original Repository

Ensure you are in the new root directory type git remote remove origin. If you get an warning about other branches, this can be ignored.

9. Add the New Repository Reference

You’ll need to create a new repo on GitHub and copy the url link for to do this. Once you have the url ready, do git remote add origin [new repo url].

10. Push All Your Files to the New Repository

git push --all 
git push --tags

11. Clone your New Repo

cd ..
git clone [new repo url] [insert new repo name]

12. Celebrate!

You’ve officially split off a subdirectory and created its own separate repo while maintaining the git history. I had to repeat these steps again to separate my frontend from my original repo as well.

If you have any questions, comments, or thoughts on how to do this better, I always love learning how to do things better. Just let me know in the comments below.

If you want, feel free to check out my split frontend and backend repos for my bookclub project I’ve been working on called On the Same Page. You can see it live here, just be patient a moment while Heroku loads it!

Keep coding and carry on. Have a great day!

Sources:

  • Dan Gitschooldude’s youtube video on splitting a repo into multiple repos
  • Nassos Michas’ blog post on maintaining git history.

--

--