Friday, June 23, 2017

Trying out Git Subtree

Currently I have 5 projects on my computer which use WinLamb library. So far I’ve been keeping copies of the library directory on each project; these directories are kept in sync with FreeFileSync Portable. Although this approach works, it’s very cumbersome.

Since each project is versioned as a Git repository, and WinLamb itself is a Git repository on GitHub, I started searching for an alternative, and I choose Subtree over Submodule. Following is a summary of the commands I needed to do on my Windows 7 x64, using Git portable v2.13.1:

1. Remote

Add a remote with the path to the repository of the shared project:

git remote add otherproj --no-tags

Or if a local project:

git remote add otherproj --no-tags d:/stuff/otherproj

You can view the remotes with:

git remote -v

2. Subtree

Run the Subtree command:

git subtree add --prefix otherproj otherproj master --squash

This will copy the library into the subdirectory and create a commit, with the hash in the message. It’s unnecessary, but you can provide a custom message for the subtree commit:

git subtree add --prefix otherproj otherproj master --squash -m "Subtreeing otherproj."

3. Updating

To update your project with new library code:

git subtree pull --prefix otherproj otherproj master --squash

This leads us to a nice bash function to our ~/.bashrc file:

function gitsubtreepull { git subtree pull --prefix $1 $1 master --squash; }

Which eases our life when updating our Subtree library:

gitsubtreepull otherproj

So far this approach seems to the better than the old-fashioned directory sync, although it still feels a bit “loose”. I’m still avoiding pushing code from the local repository to the shared library; if I change something, I just copy the code to there, then I update the library repository itself.

Note: beware amending a commit on the remote library. The next time you try to update the dependency, it’s likely to get lost, and you’ll have to remove the subtree and add it again.