As a git user you may be interested in enabling some hooks for your local git repositories. In particular, you may be interested in guaranteeing that the same policies that are being enforced by the remote repositories you push to are enforced earlier when you commit locally.
Git::Hooks only need a single script to drive all hooks implemented by yourself or by the plugins you enable. The script I use was created like this:
$ cat >~/bin/githooks.pl <<EOF #!/usr/bin/env perl BEGIN { $ENV{GITPERLLIB} = '/usr/share/perl5' }; use Git::Hooks; run_hook($0, @ARGV); EOF $ chmod +x ~/bin/githooks.pl
Without the BEGIN block I get the following error when I use it in my Ubuntu notebook:
BEGIN
$ ~/bin/githooks.pl Can't locate Git.pm in @INC (@INC contains: /opt/perl/perl5/perlbrew... BEGIN failed--compilation aborted at /opt/perl/perl5/perlbrew/.../Git/More.pm line 15. Compilation failed in require at /opt/perl/perl5/perlbrew/.../Git/Hooks.pm line 51. BEGIN failed--compilation aborted at /opt/perl/perl5/perlbrew/.../Git/Hooks.pm line 51. Compilation failed in require at /home/gustavo/bin/githooks.pl line 5. BEGIN failed--compilation aborted at /home/gustavo/bin/githooks.pl line 5.
This is because the Git.pm module can't be found in my standard @INC, since I'm using a perlbrew installed Perl. If you get the same error, you must define the environment variable GITPERLLIB in a BEGIN block before the use Git::Hooks line. In Debian/Ubuntu the module is installed as </usr/share/perl5/Git.pm> as part of the git package.
Git.pm
GITPERLLIB
use Git::Hooks
git
In order to make it easy to setup your hooks, it's useful to create a repository template for git to use when you perform a git init or a git clone.
git init
git clone
In Ubuntu, git's standard repository template resides in /usr/share/git-core/templates. If you can't find it there, read the TEMPLATE DIRECTORY section of the git help init manual to see where is your git's default template directory.
/usr/share/git-core/templates
TEMPLATE DIRECTORY
git help init
You may customize one for you like this:
$ cp -a /usr/share/git-core/templates ~/.git-templates $ cd ~/.git-templates/hooks $ rm * $ for i in commit-msg post-commit pre-commit pre-rebase > do ln -s ~/bin/githooks.pl $i > done
This copies the default template directory to ~/.git-template (you may choose another directory), removes all sample hooks and creates symbolic links to the Git::Hooks driver script which we created above for four hooks: commit-msg, post-commit, pre-commit, pre-rebase. These are all the hooks I'm interested in locally. Your mileage may vary.
~/.git-template
commit-msg
post-commit
pre-commit
pre-rebase
You must tell git to use your repository template instead of its default. The best way to do it is to configure it globally like this:
$ git config --global init.templatedir ~/.git-templates
Now, whenever you git init or git clone a new repository, it will automatically be configured to use Git::Hooks.
By default Git::Hooks does nothing. At the least, it must be configured to enable some plugins and configure them to your taste. You should read the plugins's documentation to understand them and decide which ones you would like to enable globally and which ones you would like to enable locally for particular repositories.
Here I show my personal preferences. You can take it as a baseline from which you can make variations.
This is what I have in my global git configuration (~/.gitconfig):
~/.gitconfig
[githooks] plugin = CheckLog plugin = CheckRewrite [githooks "checkjira"] jiraurl = https://jira.cpqd.com.br jirauser = gustavo jirapass = a-very-large-and-difficult-to-crack-password matchlog = (?s)^\\[([^]]+)\\] [githooks "checklog"] title-max-width = 62
The only plugins I want enabled for every repository are CheckLog and CheckRewrite. The latter is simple, as it doesn't require any configuration whatsoever. With it I feel more confident to perform git commit --amend and git rebase commands knowing that I'm going to be notified in case I'm doing anything dangerous.
CheckLog
CheckRewrite
git commit --amend
git rebase
The CheckLog is also useful to guarantee that I'm not deviating from the common git policies regarding the commit messages. The only thing I change from the defaults is the title-max-width, because I think 50 characters is very constraining.
title-max-width
The section githooks "checkjira" contains some global configuration for the CheckJira plugin, which I enable only for some repositories. Since the CheckJira plugin has to connect to our JIRA server, it needs the server URL and some credentials to authenticate. The matchlog regex makes JIRA issue keys be looked for only inside a pair of brackets at the beginning of the messages title line.
githooks "checkjira"
CheckJira
matchlog
I enable other plugins for specific repositories, since they depend on the context in which they are developed.
At CPqD we use JIRA and Gerrit internally. So, for my work-related repositories I have this in their .git/config:
.git/config
[githooks] plugin = CheckJira plugin = GerritChangeId [githooks "checkjira"] project = CDS
GerritChangeId doesn't require any configuration. It simply inserts a Change-Id line in the messages of all commits. These are required by Gerrit.
GerritChangeId
Change-Id
I use CheckJira to remind me to cite a JIRA issue in every commit message. I make two deviations from its default configuration. The project value makes it accept only issues of the CDS JIRA project.
project
To install Git::Hooks, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Git::Hooks
CPAN shell
perl -MCPAN -e shell install Git::Hooks
For more information on module installation, please visit the detailed CPAN module installation guide.