I used to work under Subversion/SVN and was instantly using nice feature called keyword substitution. Just putting in source files smth like:
/*
* $Author
Git doesn't ship with this functionality out of the box. However, there is a chapter in the Git Book on Customizing Git and one of the examples is how to use git attributes to implement a similar result.
It turns out that you can write your own filters for doing substitutions in files on commit/checkout. These are called “clean” and “smudge” filters. In the
.gitattributesfile, you can set a filter for particular paths and then set up scripts that will process files just before they’re checked out (“smudge”) and just before they’re staged (“clean”). These filters can be set to do all sorts of fun things.
There is even an example for $LastChangedDate: $:
Another interesting example gets
$Date$keyword expansion, RCS style. To do this properly, you need a small script that takes a filename, figures out the last commit date for this project, and inserts the date into the file. Here is a small Ruby script that does that:#! /usr/bin/env ruby data = STDIN.read last_date = `git log --pretty=format:"%ad" -1` puts data.gsub('$Date$', '$Date: ' + last_date.to_s + '$')All the script does is get the latest commit date from the
git logcommand, stick that into any$Date$strings it sees in stdin, and print the results – it should be simple to do in whatever language you’re most comfortable in. You can name this fileexpand_dateand put it in your path. Now, you need to set up a filter in Git (call itdater) and tell it to use yourexpand_datefilter to smudge the files on checkout. You’ll use a Perl expression to clean that up on commit:$ git config filter.dater.smudge expand_date $ git config filter.dater.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'This Perl snippet strips out anything it sees in a
$Date$string, to get back to where you started. Now that your filter is ready, you can test it by setting up a Git attribute for that file that engages the new filter and creating a file with your$Date$keyword:date*.txt filter=dater $ echo '# $Date$' > date_test.txt If you committhose changes and check out the file again, you see the keyword properly substituted:
$ git add date_test.txt .gitattributes $ git commit -m "Testing date expansion in Git" $ rm date_test.txt $ git checkout date_test.txt $ cat date_test.txt # $Date: Tue Apr 21 07:26:52 2009 -0700$You can see how powerful this technique can be for customized applications. You have to be careful, though, because the
.gitattributesfile is committed and passed around with the project, but the driver (in this case,dater) isn’t, so it won’t work everywhere. When you design these filters, they should be able to fail gracefully and have the project still work properly.