I’ve pretty much made a switch away from svn and towards git. It wasn’t easy. I loved svn and still know how to use it better than git. However, git just seems to work better for me as a single developer content management system. I’m still using svn for some of my projects (and whenever I’m ask to use it by a contractor) so it still has a place in my toolbox and in my heart. For nearly all of my new projects, however, I use git repositories.
Unfortunately, most of my other versioning tools are based on svn. I’ve been redoing them as necessary for a while but finally came to one that I must have now.
A while ago, I wrote on how to do better application versioning with svn. Basically, using the commit number of a subversion repository made it easier for me as a developer to figure out meaningful differences between versions of my application. If users reported a change between versions of an application, I would have some clue of what changed because I could compare revisions. Today, I decided that I absolutely needed this for git, too.
The problem is that git works with hashes instead of numbers. This isn’t a problem with git, it’s a problem with my system. However, it’s one that is easily remedied. git provides a lot of “porcelain” that makes it easy to build tools on top of tools. That’s essentially all I’ve done.
The first thing I do is set up a new “Run Shell Script” build phase in Xcode. Enter the following code as the script to run:
GIT="/opt/local/bin/git"
VERSION=`$GIT rev-list --all | wc -l | sed "s/[ \t]//g"`
defaults write $PROJECT_DIR/Info CFBundleVersion $VERSION
touch $PROJECT_DIR/Info.plist
Basically, we’re just getting a list of all of the revisions, getting the line count (using wc), and then stripping out all of the blank space (with sed). Then we use defaults to write the value to the Info.plist file directly. You may have to change the location of git depending on where you’ve installed it by changing the first line. I also like to touch any files that I’ve modified just to be sure that the files I’ve modified are clearly marked as changed.
Now, we’ve got the number of commits in our CFBundleVersion. The next problem is how to convert that into a meaningful git commit hash in case we need to compare commits. Well, I wrote a small Python script to handle it. That script gets all of the commits and prints the line that corresponds to the version number. Simple. You’ll have to install it in an executable location and also chmod +x it.
So now I have a basic incremental build numbering system to use in my applications that’s based on git. If you have any ideas on how I can improve this, please let me know.