June archive

Revision numbers in Subversion, Mercurial and Git

Recently, there seems to be a proliferation of revision control systems. In the django community, many started out using google code, which offers subversion, but now many projects are found in git or mercurial repositories.

Knowing the revision number is helpful in giving unique names to checked-out versions of django applications. And here's how to do that in various systems.

With subversion it's easiest to just get the revision number from the output of checkout. For example, if we want to check out dregni:

$ svn checkout http://dregni.googlecode.com/svn/trunk/ dregni-read-only ... Checked out revision 15.

Alternatively, the info command will output the revision number:

$ svn info | grep Revision Revision: 15

With mercurial, the latest revision can be found with the identify command.

$ hg identify -n 221

The revision number can be used to uniquely identify the version of the checked-out application. Note that this is only true if we're pulling from a centralized repository! Revision numbers can differ between developers (that's why there's a hash after the revision number), so if you're pulling from an independent developer you should use the entire changeset number.

Finding the revision in git is pretty much the same as in mercurial:

$ git log | head -1 commit 8952259e8d07b1e6a98897cc039853055a5d8f88

There's no helpful tiny revision number, however, so we have to use the entire commit hash instead.

But what about CVS, you say? Well, while CVS has a concept of revision numbers, these apply only to individual files and not to the entire source tree. If you do a cvs checkout you'll get the highest available version of each file (__init__.py might be version 1.1 at the same time models.py is version 1.8). As a result, if you're checking out from HEAD, the most unique version information you have is the datetime. date can print the datetime in a CVS-compatible format:

$ date +'%F %T %Z' 2009-06-11 04:04:16 CEST

But this doesn't work so well for directory naming. Using something like %F-%H.%M.%S-%Z might be better.

Alternatively, if the CVS repository has a useful tag which can be checked out with cvs checkout -r tagname, then this can be used in the same way as a revision number from subversion, etc.

django, django-tagging from debian repositories

The most recent python-django and python-django-tagging packages for debian are in the experimental repositories, but one probably doesn't want to pull all packages from experimental. APT pinning can be used to prioritize certain repositories for certain packages.

First, the repository should be added to /etc/apt/sources.list

deb http://ftp.us.debian.org/debian experimental main contrib non-free

Then in /etc/apt/preferences, each release needs to be given a priority, and certain packages should be pinned to certain releases. In particular, the django-related packages are pinned to experimental, and python-support is pinned to unstable (the django packages require a higher python-support version than is in stable).

Package: * Pin: release a=stable Pin-Priority: 900 Package: * Pin: release a=unstable Pin-Priority: 800 Package: python-support Pin: release a=unstable Pin-Priority: 1001 Package: python-django python-django-tagging Pin: release a=experimental Pin-Priority: 1001 Package: * Pin: release a=experimental Pin-Priority: 700

As noted in the previous entry, I've stopped using the debian repositories for django packages, but this is how it's done, for reference.