Search This Blog

25 August 2011

Share your git hooks

At work, we are using git for one of our projects.  One of the problems we encountered is that people (including myself) regularly forget to put the branch name in their commit message.  Why is that a big deal?  Once merged back to master, you see a lot of comments that show no indication of what they were for (for example 'added .gitignore').  I'd like to simplify things so that no one has to remember.  No need to prevent the checkin - just fix the comment...

These steps will ignore the ACLs and which server, etc... just pseudo code it...

Step 1: Setup a repo to hold the new hooks
server:/srv $ git init --bare githooks.git

Step 2: Add a new hook
server:/usr/share/git-core/templates $ rm hooks
server:/usr/share/git-core/templates $ git clone /srv/githooks.git hooks
server:/usr/share/git-core/templates $ cd hooks
server:/usr/share/git-core/templates/hooks $ nano commit-msg

#!/bin/bash

branch_name=$(git symbolic-ref -q HEAD)
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD}

OLD=`cat $1`
NEW="[$branch_name] $OLD"
echo "$NEW" > $1
exit 0

server:/usr/share/git-core/templates/hooks $ chmod a+x commit-msg
server:/usr/share/git-core/templates/hooks $ git add commit-msg
server:/usr/share/git-core/templates/hooks $ git commit -a -s -m "added commit-msg"
server:/usr/share/git-core/templates/hooks $ git push origin master

Step 3: User clones a new repo....
client:~/work $ git clone git://somerepo.git repo
client:~/work $ cd repo
client:~/work/repo $ echo "something" > test.txt
client:~/work/repo $ git add test.txt
client:~/work/repo $ git commit -a -s -m "added something"

Step 4: Checking that it worked...
client:~/work/repo $ git log

commit 07ed146319a2e45ea97b2ecaa4a1ea8d365b6b01
Author: Malachi de AElfweald <malachid@gmail.com>
Date:   Thu Aug 25 12:59:58 2011 -0700

    [master] added something
   
    Signed-off-by: Malachi de AElfweald <malachid@gmail.com>

Step 5: Updating the hook "server side"

server:/usr/share/git-core/templates/hooks $ nano commit-msg

#!/bin/bash

branch_name=$(git symbolic-ref -q HEAD)
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD}

OLD=`cat $1`
NEW="$branch_name: $OLD"
echo "$NEW" > $1
exit 0

server:/usr/share/git-core/templates/hooks $ git commit -a -s -m "changed commit-msg"
server:/usr/share/git-core/templates/hooks $ git push

Step 5: Updating the hook "client side"
client:~/work/repo $ cd .git/hooks
client:~/work/repo/.git/hooks $ git pull

Step 6: Retest it...

client:~/work/repo $ echo "something else" > test.txt
client:~/work/repo $ git commit -a -s -m "changed something else"
client:~/work/repo $ git log

commit 7f381725dd2663728f11f08d08ed0c1d83608047
Author: Malachi de AElfweald <malachid@gmail.com>
Date:   Thu Aug 25 13:33:43 2011 -0700

    master: changed something else
   
    Signed-off-by: Malachi de AElfweald <malachid@gmail.com>



3 comments:

  1. Hi Malachi, I stumbled upon this blog post through Google.

    I've been looking for ways to share hooks among our development team with minimal hassle, and this post seems to be just what we needed.

    Unfortunately, I can't get it to work...

    If I make any changes in server:/usr/share/git-core/templates/hooks they are simply not transferred to the client during "git clone". It appears the Git client reads the initial hooks from client:/usr/share/git-core/templates/hooks and just ignores any hook modifications made on the server.

    I must be missing some step here. Help?

    ReplyDelete
  2. I'm not sure about this, but I believe he may have a clone of the "hooks" repository -- an entirely different repository from the /work/repo repository -- in the .git/hooks folder of the /work/repo working copy.

    Malachi, can you let us know if that is your approach?

    ReplyDelete
  3. It's been awhile since I looked at this, but that is essentially correct. When the repo is cloned, it copies the template (which now has a .git directory in it) so that your .git/hooks directory is also a git clone (of the server hooks).

    Not elegant, but doable.

    ReplyDelete