Automatic version numbers with Git

One thing I like about Subversion is its keyword substition. For me, $Revision$ or simply $Rev$ is handy when I don't want to pay attention to the versioning of some code snippets or configuration files. Git does not offer such keywords. My approach uses hooks to built around this limitation.

Hooks

I've used the pre-commit and post-commit hooks. The first one saves the name of all modified, added, renamed, copied, or updated files, which are subject of the current commit. The latter one replaces $Rev$ with $Rev: 23 in these files, where 23 is the count of all previous commits, and then commits these files again.

pre-commit

Create .git/hooks/pre-commit and make it executable:

#!/bin/sh

STATUSFILE=".zzz-git-status"

# doesn't work as pre-commit gets no terminal or stdin
#read -p "Create new version (y/n)? " NEWVER
#[ "${NEWVER}" = "y" -o "${NEWVER}" = "Y" ] || exit

IFS=""

git status -s | while read LINE; do
  FILENAME="${LINE#[MARCU ][MARCU ] }"
  [ "${FILENAME}" = "${LINE}" ] && continue
  FILENAME="${FILENAME#\"}"
  FILENAME="${FILENAME%\"}"
  echo "${FILENAME}"
done > "${STATUSFILE}"

[ -s "${STATUSFILE}" ] || rm "${STATUSFILE}"

post-commit

Likewise, create .git/hooks/post-commit and make it executable as well:

#!/bin/sh

STATUSFILE=".zzz-git-status"

[ -f "${STATUSFILE}" ] || exit

REVISION=`git rev-list --all --count` || exit 1
# or use previous commit's hash:
# REVISION=`git show HEAD^1 --format="%p" -q`

while read FILENAME; do
  sed -i "" 's/\$Rev[^\$]*\$/\$Rev: '"$REVISION\$/g" "${FILENAME}" || exit 1
  # For GNU sed on Linux:
  # sed -i"" 's/\$Rev[^\$]*\$/\$Rev: '"$REVISION\$/g" "${FILENAME}" || exit 1
done < "${STATUSFILE}"

rm "${STATUSFILE}" || exit 1

exec git commit -a -m "Version ${REVISION}" -n

Notes