Use 'git subtree' to create new repository from a sub-directory

As a part of my ongoing Ansible blog series, I plan to walk-through the provisioning code of CentOS Containr Pipeline service which lives under provisions directory.

My plan:

For the second part, i.e., modifying the code without touching my fork, I needed to create a new git repository from the said provisions directory.

A bit of Google-fu and this stackoverflow answer came to rescue! All I did was, use this git subtree command to create a new branch that holds the code I’m interested in:

$ git subtree split -P provisions -b provisions-only

Here, provisions is the directory I want to create a new git repo out of and provisions-only is the branch that will hold the code that’s inside provisions directory

Create a new directory outside the directory holding my fork of the repo and do git init:

$ mkdir ~/repos/cccp-provisions
$ cd ~/repos/cccp-provisions
$ git init

And git pull from the fork to new directory:

$ git pull ~/repos/container-pipeline-service provisions-only

Here, ~/repos/container-pipeline-service is the path to the forked repo that I don’t want to touch and provisions-only is the branch in that repo that holds the code I’m interested in.

Whenever there’s a change in the big repo (container-pipeline-service) and I want to copy the changes to cccp-provisions repo, all I need to do is execute the same git subtree command I used above in the big repo, and do git pull --rebase in cccp-provisoins :

$ cd ~/repos/container-pipeline-service

$ git diff --unified=0
diff --git a/ b/
index fd32557..fb14f4f 100755
--- a/
+++ b/
@@ -0,0 +1,2 @@
diff --git a/provisions/ b/provisions/
index f956524..67f70dc 100644
--- a/provisions/
+++ b/provisions/
@@ -0,0 +1,2 @@

$ git add -A

$ git commit -m "Test"

$ git subtree split -P provisions -b provisions-only
Created branch 'provisions-only'

$ cd ~/repos/cccp-provisions

$ $ git pull --rebase ~/repos/container-pipeline-service provisions-only
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/dshah/repos/container-pipeline-service
 * branch            provisions-only -> FETCH_HEAD
Updating d203d40..3dc4752
Fast-forward | 2 ++
 1 file changed, 2 insertions(+)

What I did above was: modify two files; one inside the provisions directory and one outside it; committed the changes it to my master branch and using the git subtree command, created a provisions-only branch like we did earlier. When I go to the cccp-provisions directory and do git pull --rebase, git knows that only one of the two files modified in that commit is of our interest and so it changes only one file:

Fast-forward | 2 ++
 1 file changed, 2 insertions(+)

That was pretty cool for me! Now I can go ahead and walk-through the provisioning bits and also make changes to it without affecting my fork of the repo.