Header

How to move a subdirectory into a separate Git repository

Using the git subtree command to move a subdirectory in your repository into it's own Git repository

It may be useful to detatch or move a subdirectory in your repository, out to an external repository, especially if you want to re-use the contents of said subdirectories across multiple repositories.

You can then commit and push updates to the subdirectory separately, and any other repositories can pull the updates, without having to maintain 3 different copies of the same code.

Using the git subtree function, you can easily split a subdirectory out to a new branch, create and link the new repository then push it.

Preparing the current repository

$ cd path/to/repository
$ git subtree split -P my-folder -b my-folder
Created branch 'my-folder'
aecbdc3c8fe2932529658f5ed40d95c135352eff

The name of the folder must be a relative path, starting from the root of the repository.

Creating the new repository

$ cd my-folder
$ git init
Initialized empty Git repository in /Users/adamwest/Projects/learngit/shop/my-folder/.git/
$ git add .
$ git commit -m "initial commit"
[master (root-commit) 192c10b] initial commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 file

Here we just need to cd to the new folder, initialise the new repository, and commit any contents.

Add new remote repository and push

$ git remote add origin git@github.com:robertlyall/my-folder.git
$ git push origin -u master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 199 bytes | 199.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:robertlyall/my-folder.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

We add the new repository remote from GitHub here, then push our first commit to it.

Remove folder from main repository and push

$ cd ../
$ git rm -rf my-folder
rm 'my-folder/file'
$ git commit -m "Remove old folder"
[master 56aedbe] remove old folder
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 my-folder/file
$ git push
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 217 bytes | 217.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:robertlyall/shop.git
   74dd8b3..56aedbe  master -> master

Finally, we cd back to the rooot directory, remove the folder from our main repository, then commit and push the change.

Now, we have the folder in our main repository but linked to a completely separate repository that can be reused across multiple projects.