Using GIT and VI together

December 27, 2008


A long while back I used vi together with rcs to manage files in /etc. This worked, but I found rcs to be clunky. So welcome to the 21st century and my git + vi script.

It is a wrapper around git, which will create a new git repository, add the file and commit it when changed.

The script will also expand $Hash$ to

$Hash: basename-of-file short-commit-hash epoch committer`

a typical example is

$Hash: motd.tail 2ebb8e9 1230404370 miekg $

This is somewhat the same as the $Id$ tag from svn/CVS, but with a different tag. I always found this tagging from subversion useful, esp. when you – as a human – needs to tell if a file is under version control.

To avoid accidental edits the file is set to read-only.

I think I’m gonna dump cfengine and just use this script, cfengine is great, but somewhat of a overkill for my home setup.

Sourcecode of the script

The script uses zsh, but can be easily converted to bash or any other shell.

# a wrapper around git and vi
# expands $Hash$ to $Hash: file short_hash epoch committer $
# git checkout HEAD $file? when would I need this

[[ ! -x =git ]] && exit 1


for file in "$@"; do

dir=$(dirname $file); cd $dir

chmod +w $file 2> /dev/null

if [[ ! -d .git ]]; then
    git init || exit 1

if vi $file; then
    [[ ! -e $file ]] && exit 0
    git add $file
    # collapse $Hash: id $ line
    sed -i -e 's/\$Hash:.*\$/$Hash$/' $file
    git commit $file

id=$(git-show -s --pretty=format:$(basename $file)\ %h\ %ct\ $who%n -- $file) 
[[ -z $id ]] && exit 1

# re-add $Hash: sha1hash$ line
sed -i -e 's/\$Hash\$'/\$Hash:\ $id\ \$/ $file

chmod a-w $file 2> /dev/null


I just thought of something, what if there already is a git repository in a higher directory….Hmmm. This means the script should look for a git repository higher up and work from there….