Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show the latest commit value within a web application?

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

like image 733
dannymcc Avatar asked Oct 22 '10 16:10

dannymcc


People also ask

How can I see last commit details?

If you want to see what's happened recently in your project, you can use git log . This command will output a list of the latest commits in chronological order, with the latest commit first.

How Get latest commit in branch?

If you need to get latest commit on a branch through the REST api, try the "/commits" call with the "until" parameter set to the branch you are interested in, and limit=1 to get the single tip commit from the branch.

How Get latest commit from remote branch?

To do that, leverage the Git checkout command to retrieve the latest commits from a remote branch on a remote Git repository. With a configured remote branch, Git will instead mirror a remote branch instead of a local-only branch. An example of the command git checkout remote is shown below.

How do you see which commit I am on?

You can also simply do git log -1 to find out which commit you're currently on.


1 Answers

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 better git describe --dirty (the --dirty option would make returned string contain information whether you have uncomitted changes in working area), or git describe --always HEAD.

git rev-parse HEAD gives something like 7611062b4ba6d1ebc4cf3e63c11204a4f5057660, while git describe --dirty gives something like v1.7.3.2-95-g7611062 (which means commit with abbreviated SHA-1 of 7611062, 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!):

require 'grit'
include Grit

repo = Repo.new("/var/git/app.git")
head = repo.commits('HEAD', 1)

app_version = head.id


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 which filter attribute should act:

*.rb filter=commitid

You define filter in git config file (e.g. in .git/config), for example

[filter "commitid"]
        smudge = sed -e "s/\$Revision: ?\$/\$Revision: $(git rev-parse HEAD)\$/1"
        clean =  sed -e "s/\$Revision: ?[^$]*\$/\$Revision: \$/1"

The 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). The clean 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 setting export-subst for given file, for example by adding to .gitattributes file

*.rb export-subst

and then adding to your file that contains/generates page footer e.g

$Format:%H$

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 uses sed for that.

like image 109
Jakub Narębski Avatar answered Sep 25 '22 01:09

Jakub Narębski