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 "raphael.b_____r@gmail.com"
You can override this values per repository:
$ cd some-ippon-project
$ git config user.email "rbrugier@ipponusa.com"
## print the configuration
$ git config user.email
> rbrugier@ipponusa.com
Git hooks
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 = raphael.b_____r@gmail.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 ~/devs/github/
or ~/devs/projects/
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 "rbrugier@ipponusa.com"'
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.
Result
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 "rbrugier@ipponusa.com"
Conclusion
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.