How to Move Subdirectory Into New Git Repository?

Wednesday, February 2, 2022 • 3 minutes to read

I have had to move one of the subdirectories of a Git repository to a new one. I needed to keep the commits history on the new repository. But, of course, only that relevant part of history for my subfolder. Looking on the Internet for a solution, I have found a lot of articles suggesting filter-branch, but it turns out it is not the best solution. At least for me.

Let’s start with clearly defining what we want to do. We would like to have a new repository with the content and commits history, including merges, of a subfolder from some other repository. Let’s assume the subdirectory name is docs and will create a new repo called docs-repo.

How to split a subfolder content and history into a new branch?

The easiest way to achieve our goal will be using Git subtree command. The following command will create a new branch with history prefixes with docs.

$ git subtree split -P docs -b docs_branch

What does it mean? The new history includes only the commits that affected our subfolder docs, and each of those commits now has the contents of docs at the root of the project instead of in a subfolder.

In plain words, our docs_branch has all history of our docs subfolder as is no other part of the old repo exists. This command does not change anything in the original repository or amend any history.

There are some essential remarks here. First, repeated splits with the same prefix (-P) produce the same commit ID; thus, every command’s call creates the same history tree. This command will not be suitable if you split multiple subfolders with different names.

How to create a new repository from a branch?

After the previous command, you will have a branch with the desired data and history, and you can initialize a new repository based on it. The following commands will create a repo and pull the branch as a new master branch.

$ git init docs-repo
$ cd docs-repo
$ git pull ../original_repo docs_branch

You can add a remote, empty repository as the “origin” one and push the “master” branch if you desire.

$ git remote add origin remote_repo
$ git push -u origin master

In the end, you can remove the subfolder which we successfully split from the original repository and commit your changes.

How can I remove history from the Git repository?

The short answer is, you cannot. Or, to be more precise, you cannot if you published your repository before the split. The history of our deleted folder is still in the repository, although the files are not there.

There is an option to remove the history, the filter-branch command, at the beginning of this article.

$ git filter-branch --prune-empty --tree-filter 'rm -rf docs' HEAD

You will notice that the history of that folder is not existing when you run git log, but when you want to push it to the remote repository, you will not be able to do it unless you call git pull, which will, of course, recover the history.

On the other hand, in “Git best practices”, I describe why you should not rewrite any history. So please do not do it.

developmentgitvcshow to
See Also
This site uses cookies to analyze traffic and for ads measurement purposes according to your browser settings. Access to those cookies is shared with Google to generate usage statistics and detect and address abuse. Learn more about how we use cookies.