December 3, 2016
I use Git a lot and I often have to switch between my personal repositories (ie: Github) and my professional (Ippon) repositories on the same laptop. My default Git email is configured to my personal email and I have often forgotten to configure it to my professional email when creating/cloning a repository for my company. Like everything in Git, this can be automated to avoid mistakes.
In this post, I will show how I use a Git hook to check the email configured in any repository before every commit.
Email configuration per repositories:
When you first installed Git you probably have set your username and email globally with these commands:
$ git config --global user.name "Raphael Brugier" $ git config --global user.email "firstname.lastname@example.org"
You can override this values per repository:
$ cd some-ippon-project $ git config user.email "email@example.com" ## print the configuration $ git config user.email > firstname.lastname@example.org
Git hooks are scripts that Git executes before or after Git commands. For example: commit, push, rebase, …
They are located in every Git repository in the .git/hooks/ folder. By default, Git creates hooks suffixed with “.sample” To create a custom hook, create a new executable script without the suffix for the hook you want to create and add the Bash code for your needs:
$ vim .git/hooks/pre-commit ## add the hook code as any bash script $ chmod +x .git/hooks/pre-commit
Global Git hooks
Since its version 2.9, Git offers an option to share the hooks globally between the repositories. I prefer this option to duplicating hooks in every repository, even if you could use templates to automatically copy them in every new repository.
Create a hooks folder, for example in your dotfiles, and configure Git globally to use this folder as the hooks folder for every repository:
$ mkdir -p ~/dotfiles/_git/hooks/ $ git config --global core.hooksPath ~/dotfiles/_git/hooks/
Git has added the option in your global Git config:
$ cat ~/.gitconfig ... [user] name = Raphael Brugier email = email@example.com [core] hooksPath = ~/dotfiles/_git/templates/hooks/ ...
Check email hook
The goal is now to use a hook to validate the email set in the repository before committing.
I follow a simple convention to differentiate my personal and professional repositories.
My professional repositories are located on
~/devs/ippon and my personal on
Write a bash script to check the email configured based on the repository’s path as a pre-commit hook :
$ vim ~/dotfiles/_git/hooks/pre-commit
#!/bin/sh PWD=`pwd` if [[ $PWD == *"ippon"* ]] # 1) then EMAIL=$(git config user.email) if [[ $EMAIL == *"ippon"* ]] # 2) then echo ""; else echo "email not configured to Ippon in Ippon directory"; echo "run:" echo ' git config user.email "firstname.lastname@example.org"' echo '' exit 1; # 3) fi; fi;
- check if the current path contains “ippon”
- check if the configured email also contains “ippon”
- if not, exit the script with an error. This will cancel the commit.
Test the hook is working in a new repository:
$ mkdir -p ~/devs/ippon/testhook/ $ cd ~/devs/ippon/testhook $ git init $ git commit -m "test" > email not configured to Ippon in Ippon directory > run: > git config user.email "email@example.com"
Git hooks are powerful to automate tests and avoid mistakes. Other common usages of hooks are to trigger tests before a commit or a deployment after a push.