I have a few Rails applications and I use Git as the version control system. I use either GitHub or Beanstalk as the repository hosts.
What I am trying to is quite simple in theory. Somehow show the latest commit ID number (hash?) in the footer of the web application. So that when I am looking at the web application I can check that it's committed and deployed correctly.
I can imagine there are two methods to tackle this. The first would be a possible feature of Git that allows the output of the commit ID. The second would be a post-commit web hook (both Beanstalk and GitHub allow this).
Has anyone ever found a way to do this, or something similar?
Thanks,
Danny
First, the answer to your question, run the following command in your ruby script:
Second: What do you mean you use beanstalk as your repository host? Isn't beanstalk a queueing server?
First, a clarification:
post-commit
hook cannot add commit-id to file in a commit, because commit id depends on commit of the top tree (representing top directory), id of top tree in turn depends on ids of its members, and id of a file depends on its contents... and this content is to include commit id. Not possible.But let's take a look at different solutions:
Live, server side scripting
If your web app is deployed live from non-bare git repository (I hope you know what you are doing wrt. pushing into non-bare repository, i.e. repository with checkout / working tree), then your web app can check HEAD by using
git rev-parse HEAD
(gives SHA-1 of commit), or bettergit describe --dirty
(the--dirty
option would make returned string contain information whether you have uncomitted changes in working area), orgit describe --always HEAD
.git rev-parse HEAD
gives something like7611062b4ba6d1ebc4cf3e63c11204a4f5057660
, whilegit describe --dirty
gives something likev1.7.3.2-95-g7611062
(which means commit with abbreviated SHA-1 of7611062
, 95 commits after commit tagged 'v1.7.3.2'), but it depends on you tagging releases using annotated tags.A variant of this would be to have web app to check HEAD from repository which is somewhere else on the same filesystem, e.g. with
git --git-dir=/path/to/.git describe HEAD
.Sidenote: if you use Ruby, you probably want to use grit library. The equivalent of
git rev-parse HEAD
version would probably be (untested!):Live, static files served from git checkout
Edit: section added 2010-10-23 13:33 +0000
If you serve your files from checkout (worktree) of non-bare git repository (not your situation), you can use 'smudge' and 'clean' commands of
filter
gitattribute to perform CVS-like keyword expansion on checkout / checkin.In
.gitattributes
file you would define files on whichfilter
attribute should act:You define filter in git config file (e.g. in
.git/config
), for exampleThe
smudge
filter would replace '$Revision: $' with e.g. '$Revision: v1.7.3.2-95-g7611062' on checkout (this means that checked outfiles would contain this CVS-like keyword expanded). Theclean
filter would remove expansion when storing file contents in git object database (in git repository); otherwise you would have problems with comparing file etc.Deployed with use of
git archive
If you instead deploy your web app, so it doesn't reside in live repository (which has its quirks wrt. pushing into it, and which has possible security drawbacks), and you use
git archive
somewhere (e.g. to zip app to upload it to your hosting site), you can make use of keyword substitution.First you need to tell Git that you want keywords in a file replaced by
git archive
. You do that by settingexport-subst
for given file, for example by adding to.gitattributes
fileand then adding to your file that contains/generates page footer e.g
which will be replaced by commit hash (see pretty-formats description e.g. in git-log manpage).
Deployed, using some deployment script
If you use some kind of script / scripted mechanism to deploy your web app, you should follow Jefromi advice of having your deploy script embed version information.
You would have to ask somebody else how to set Capistrano (assuming that you use it for deployment) to post:deployment replace '@@VERSION@@' placeholder in your 'app.rb' file with result of
git describe --always HEAD
... Git project Makefile usessed
for that.I believe what you'll end up wanting to do is, as a part of your "build" process (deployment, your case?), store the output of
git rev-parse HEAD
orgit describe HEAD
(better, assuming you tag releases) in a file. Your app can then display the contents of the file. The commit hash can't ever actually be part of any tracked content (the hash of the commit depends on the tracked content). Of course, if your app is running out of a repo, you could simply run the command from the app, but it's a lot more elegant to just do it once.This is the approach taken by git itself, by the way. It has a teeny shell script which basically dumps
git describe
output toGIT-VERSION-FILE
, which is then compiled in to provide the version information.Hopefully I haven't misunderstood your situation - I'm a little confused by you saying "a possible feature of Git that allows the output of the commit ID". This is a very basic capability of git.