# Git filtering Excellent [idea Ton](http://tonkersten.com/archives/2009/08/10/my_git_hash_filter/index.html)! How to make a custom filter in `git` to expand the string `$Hash$` to something more usefull, ala the `$Id$` (which `git` already supports), but then with more info (committer, date, etc.). Which also helped in this case was the [Pro Git book](http://progit.org/book/ch7-2.html) which is, as of now, a must buy. But as always is the case between Ton and me, I find his scripts too long :-) So I *miekified* his solution. First we need two scripts, one to expand $Hash$ and another one to collapse it again: `git.expand`: #!/bin/sh id=$(git show -s --pretty=format:%h\ %ci\ ${SUDO_USER:-${LOGNAME}}%n) sed -e 's!\([[:space:]]*\$[H]ash\)\$!\1: '"${id} "'\$!' and `git.collapse`: #!/bin/sh sed -e 's!\([[:space:]]*\$[H]ash\):.*\$!\1\$!' And a final check to see if they are working: % echo '$Hash$' | git.expand $Hash: 8c84acf 2009-08-11 19:28:20 +0200 miekg $ Looking nice. % echo '$Hash$' | git.expand | git.collapse $Hash$ Wonderful - the scripts work. Now we need to set up the filtering in `git`. # Filtering As Ton also explained you need to add the filtering commands to your global `~/.gitconfig` and then edit a `.gitattributes` to enable this on a per repository basis. In `~/.gitconfig` add: [filter "hash"] smudge = git.expand clean = git.collapse And in your `.gitattributes` add: * filter=hash See gitattributes(5) for more information on this. # Test Now run a little test: % echo '$Hash$' > h % git add h % git commit -m'testadd' -- h Created commit b5189fd: testadd 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 h And, and... and...: % cat h $Hash$ Huh, unexpanded? Well yes, you need to remove and checkout the file for it all to work: % rm h && git checkout -- h && cat h $Hash: b5189fd 2009-08-11 19:50:19 +0200 miekg $ # Putting it all together So now I only need a little wrapper around `vi` and `git` to do all this automatically. So here is `vit2`: CODE(sh){ #!/bin/zsh # (c) Copyright Miek Gieben, 2009 Licensed under GPL v3 # expands $[H]ash$ to $[H]ash: short_hash date committer $ # with the help of git filter zparseopts -D -K -- m:=o_msg # -m mesg is supported [[ $? != 0 ]] && exit 1 o_msg="$o_msg[2]" for file in "$@"; do dir="$(dirname "$file")" cd "$dir" 2>/dev/null || continue base="$(basename "$file")" chmod +w "$base" 2>/dev/null if ${EDITOR:-/usr/bin/vi} "$base"; then [[ ! -e "$base" ]] && exit 0 # nothing saved git add "$base" if [[ -z "$o_msg" ]]; then git commit -- "$base" else git commit -m "$o_msg" -- "$base" fi rm "$base" && git checkout -- "$base" fi chmod a-w "$base" 2>/dev/null cd - >/dev/null done }CODE That's all folks! And thanks [Ton](http://www.tonkersten.com).