Monday, February 08, 2010

Splitting a git repo

Its been almost an year since I last blogged and what can I say, micro-blogging killed blogging for me. Even micro-blogging has got to a point, I don't do as much as I used to. Perhaps the end of web 2.0 or perhaps I'm getting too old for this :)

Anyhow, getting back to the subject of this quick post, it seems splitting a git repo into two separate git repos is somewhat obscure and required a bit of googling around. Fortunately I came across this great blog post, but wanted to summarize it in one place (the author made me look at several pages to put it together).

Say I have a git project called foo.repo which had a subdirectory called bar, that I now want to make its own separate git project called bar.repo.

Current state

foo.repo/
.git/
bar/
abc/
xyz/


target state

foo.repo/
.git/
abc/
xyz/

bar.repo/
.git/



Step 1 : Clone existing repo as desired repo on the local clone


$ git clone --no-hardlinks foo.repo bar.repo


Step 2: Filter-branch and reset to exclude other files, so they can be pruned:


$ cd bar.repo
$ git filter-branch --subdirectory-filter bar HEAD -- --all
$ git reset --hard
$ git gc --aggressive
$ git prune


Step 3: Create new empty repo on git server


$ mkdir /var/git/bar.git
$ cd /var/git/bar.git
$ git --bare init



Step 4: Back on the local machine, replace remote origin to point to new repo


$ cd bar.repo
$ git remote rm origin
$ git remote add origin git@git-server:bar.repo
$ git push origin master


Step 5: Remove bar directory from original foo.repo


$ git filter-branch --tree-filter "rm -rf bar" --prune-empty HEAD

or supposed to be faster, I haven't tried
$ git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch bar" --prune-empty HEAD




Reference