Git hooks are one of the most underrated git features, and have the potential to increase your productivity as a developer. Have you ever wanted to run a command every time you or ? Lucky for you, that’s exactly what git hooks do — they’re custom scripts that run before or after git commands to automate manual tasks. Read on to find out how hooks could improve your workflow. commit push Why use git hooks? I came to learn about hooks after embarking on a quest to automate my own workflow. You see, for better or worse, I make use of comments in my code to remind myself to revisit something. My usual process involved doing a global search for “ ” before committing, however I’m sure you can already see plenty of room for human error. FIXME: FIXME: Hooks came to my rescue. I was able to create a simple hook (code at bottom of post) that looks for comments in my attempted commits, and stops the commit it if any are present. pre-commit FIXME: What if I to commit one of those comments? Hooks are easy to override if they become a blocker. By supplying the parameter to the command (e.g. ), the associated hooks will be skipped over completely, allowing the command to continue. wanted --no-verify git push --no-verify Since hooks can easily be skipped, it’s better to use a build pipeline if you have a process that be enforced. must There are 17 hooks in total — some that execute before a command, and some that execute after. You can use hooks to enforce commit message length, ensure adequate test coverage, prevent secrets from being committed, or just print out fun ASCII art. The possibilities are endless. Setting up hooks Hooks can be set up in two ways — they can run for every repo on your machine, or only run within a specific repo. There are benefits to either method: Global Hooks Added in version 2.9.0 of git, global hooks are executed for every repository. These are a great option if you have personal workflows that apply to every repository you interact with. Git will automatically look for global hooks in the configured folder, and invoke any it finds. hooks The default location for global hooks is: . If you want to change the location of that folder, you can run the following commands (replacing with your desired path): $GIT_DIR/hooks ~/.githooks Repo Hooks Repo hooks only run for the repo in which they live, and will be skipped if a global hook of the same type exist. These hooks should be placed in the directory within the repo. They’re a great option if you have hooks that are very specific to a project. .git/hooks Keep in mind that you can’t commit hooks with your repo — they stay on your local machine. But if you think about it, committing hooks would be a security nightmare. It could give would-be attackers full access to run malicious scripts on your machine without your knowledge each time you clone a new repo. Creating hooks Now for the fun part. As mentioned above, there are 17 hooks you can implement. Some of my favorites are: : occurs before a is executed, and can prevent the commit from happening. pre-commit git commit : occurs after a , and is primarily used for notifications since it cannot affect the outcome of execution. post-commit git commit : occurs before a , and can prevent the push from happening. pre-push git push : occurs before a , and can edit a commit message before it’s applied. prepare-commit-msg git commit Creating a hook is as simple as creating a file with the same name as the hook you wish you implement (e.g. ) and making it executable ( ). ← .git/hooks/pre-commit chmod +x pre-commit The executable part is key, otherwise git will ignore the file and move on. As mentioned above, if the hook occurs an operation (e.g. , ), you have the power to prevent the command’s operation. To stop execution, the hook must exit with a non-zero status (e.g. ). Otherwise, you’re free to log messages, or anything else your heart desires. before pre-commit pre-push exit 1 Hook example To sum it all up, I present you with the shell script I created to solve the dilemma from the beginning of this article. Any language can be used to write a hook, but Shell and Python are common choices. FIXME: If you want to repurpose this script to search for a different string that shouldn’t be committed, you can modify the variable to look for any substring in incoming commits. SEARCH_TERM What do you think — are git hooks useful for your workflow? Feel free to share any hooks you’re using in the comments below. If you found this article helpful and would like to see more like it, please let me know by leaving some claps. 👏