Global Hooks with Git
Tags: git
Published: 2019-02-20 18:35:46

---
title: Global Hooks with Git
published: true
description: A guide to using global git hooks without overriding the local hooks
tags: git
canonical_url: https://eidson.info/post/global-hooks-with-git
---

Originally posted on my personal [blog].

# Global Hooks with Git

## Introduction

Recently I began to wonder if there was a way to have a collection of [git hooks] that could run on all of my git projects to save me the trouble of creating/editing hooks in each of my projects.  Yes, it is possible to do this for new projects, via the `git config --global init.templatedir` command, but I have a lot of pre-existing git projects that I wanted to add a pre-push hook to, and I wanted to be able to make alterations to this hook after the fact that would affect all my projects.  Apparently, I'm not the only person who needed this feature, because it was added in git release 2.9.

## Details

Adding the global hooks was easy enough, thanks to this [stackoverflow] answer, but I did run into a couple of caveats after I had the global hooks path set.

### git config

To add the path to your global git configuration run the following command:

```bash
git config --global core.hooksPath /path/to/my/centralized/hooks
```

### Hook file

The next step is to add your hook file and make it executable.

```bash
touch /path/to/my/centralized/hooks/pre-push
chmod a+x /path/to/my/centralized/hooks/pre-push
```

And then add what ever logic you'd like the hook to execute.  I use [sonarqube] to provide Continuos Inspection to my projects, so I wanted the `sonar-scanner` to run on every push.  (I highly recommend [sonarqube] for keeping bugs and code smells out, you should check it out if you're not familiar with it!).  I use the [fish shell], so you might need a different shebang.

```bash
# /path/to/my/centralized/hooks/pre-push
#! /usr/bin/fish

command sonar-scanner
```
So I created my hook and did a test push, to see that it worked as expected.  However, I do have some documentation only and small script projects that don't use the `sonar-scanner`.  I was getting some ugly error messages when pushing these projects.  It didn't fail the push, because I wasn't checking the return code on `sonar-scanner` command, but I still wanted to silence these messages, or not run `sonar-scanner` at all on projects that didn't need it.  That was easy enough to do by checking for the presence of the `sonar-project.properties` file before running the scanner.

```bash
# /path/to/my/centralized/hooks/pre-push
#! /usr/bin/fish
if test -e ./sonar-project.properties
    command sonar-scanner
end
```
Ok, so now that is running only when it should, but I bumped into another issue.  I had some projects that had project specific pre-push hooks that I expected to still be running before a push was executed.  I had assumed that adding these global hooks would be in addition to the project hooks, not overriding them.  However, that is not the behavior I was wanting; I still wanted any project specific hooks to be executed.  The fix for this was to check for the existence of a project level git hook and fire it if it exists.  I decided it would make more sense for my use case to fire it before the global hook logic was executed.

```bash
# /path/to/my/centralized/hooks/pre-push
#! /usr/bin/fish

if test -e ./.git/hooks/pre-push
    command sh ./.git/hooks/pre-push
end

if test -e ./sonar-project.properties
    command sonar-scanner
end
```

## Conclusion

So there I had my global hook, that only ran the `sonar-scanner` if it was necessary and made sure to also execute any local hooks. I'm sure I've only scratched the surface of the power of this, and I'm looking forward to adding more functionality in the very near future.  I'm going to investigate failing the push if the [sonarqube] quality gate fails, next.  To improve my CI/CD work flow.  Have any suggestions or ideas for better hooks?  Please leave them in the comments below.


[blog]: https://eidson.info/post/global-hooks-with-git
[git hooks]: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
[stackoverflow]: https://stackoverflow.com/a/37293198
[sonarqube]: https://www.sonarqube.org/
[fish shell]: https://fishshell.com/