Get hooked !! Photo by on Alvaro Reyes Unsplash Overview If you’ve ever worked on an open-source project, or you’re working in a team, it’s very likely you are using some kind of version control. Version Control System( ) has become one of the major requirement for any project, Git being the most popular one. However, as the team grows in number, it becomes difficult to handle the different code styles and to enforce certain rules across all the contributors. These issues aren’t noticed by a contributor until he has pushed his changes which result in overheads for the core maintenance team. To enforce these rules and validate the code being pushed, Git has a great feature, called Git Hooks. VCS What are Git Hooks? These are custom scripts which are triggered on certain specific git events. Hooks allow defined scripts to run before, or after, certain Git events occur. There are two types of hooks : Client Side Hooks Server Side Hooks Server Side Hooks, as the name suggests, are installed on the server and are triggered only in case of network operations. For example - Post-Receive is a type of server-side hook triggered after a successful push. This makes it a perfect place to send out the notifications to all the other contributors. Client Side Hooks reside on one’s local repository and are executed when a git event is triggered. Here, a git event can be , , etc. When we run certain git commands, git look for the hooks within the git repository to see if there is an associated script to run. For example, one could have a hook to validate that the code enforces certain rules before it’s pushed to the remote repository. Since we can’t do much in the case of server-side hooks, we will talk about client-side hooks only for the rest of the article. commit push rebase pre-push Executing your hooks !! 😎 In this section, we will take a deeper look at hooks and see one of the hooks in action. We will execute a simple hook to validate that the code being pushed doesn’t have any commit with ‘WIP’ in the commit message. (WIP — Work in Progress). Let’s Begin!! First, let’s create a new directory. Create a new folder — ‘hooks’ Now, initialize a git repository in the same folder with . We can see, initializing a repo creates a hidden folder . The hidden files and folders can be viewed using flag. flag shows the basic details of the files. So, combining both the flags, we can have to view the details of all the files present in a directory. Since we will be working a lot with hidden files, we are going to use throughout the article. git init .git -a -l ls -la ls -la git init But, what’s inside the mysterious ? Let’s have a look. Simply put, it contains all the metadata related to your git repository including commits, remote repository address etc. It also contains a log of all the commits. If you look closely, you can see a folder. This is where all the magic happens! .git folder hooks Content of .git folder So, let’s have a look at the folder. It has a sample script for all kinds of hooks. Since these files end with a extension, these are not executed on the specified git events. For example, file would be executed prior to any commit if we rename it to . And that’s exactly what we are gonna do 😂 ! hooks .sample pre-commit.sample pre-commit Hooks folder First, let’s understand one of the existing hook, . pre-push.sample If it seems like too much, you can have a look at the comments at the top of the file. Basically, it looks for all the latest commits in your local repo and checks if the new commit message has the string ‘WIP’ in it. To find the commits, it takes into account the remote repository hash and the current local repository hash, and looks for all the commits between the two. If it finds the string, it prints the and aborts the push. Note that if the script ends with a non-zero exit code, it won’t push to the remote repo. Found WIP commit in... Let’s test this quickly. Till now, we have initialized our git repo locally but it needs a remote repo to push. So, create a new repository on GitHub (or BitBucket) and copy the remote git url. I created one named . hooks-demo Now, we need to add this remote reference to our local git repository using . git remote add origin "url" Adding reference Now, Let’s create a new file with some text. Commit the file and then push it, it should get pushed with no issues. index.html Push successful Now, let’s apply the magic and make the hooks executable. Rename the pre-push.sample file : . Just make sure the file is executable. In case, it’s not, would help. mv .git/hooks/pre-push.sample .git/hooks/pre-push chmod +x filename Renamed the file With all these done, change the content of the file and do a new commit with ‘WIP’ word in it. pre-push hook in action The push failed. Since we removed the extension of the file, the file was executed and hence the push didn’t go through. ta-da !! 😍 Similarly, based on your requirement, you can write your own hooks to enforce certain rules. In the example above, we checked for a particular string in the commit message but what if, we want to ensure that a particular string is not present in the committed code. Well, we can use pre-commit hook for that. The above pre-commit hook will look for a ‘TODO’ string in your commit. If it finds one, the commit will be rejected. What if you want to commit with ‘TODO’ ? Since these hooks are installed on local machines, they can always be bypassed. git commit --no-verify Using the flag won’t trigger hooks. _--no-verify_ We have used bash script for the above examples. However, it supports any scripting language that your system can execute. How to bring the team on the same page? Let’ say, You’ve written a ‘pre-push’ hook which don’t allow anyone to push the code if it has word in it. It’s cool and it’s working great for you. Now, how are you gonna distribute this script to others working on the same project? As I mentioned, hooks are present in folder along with all the other git metadata. Since the data can be user-specific, folder is not versioned, meaning the contents of this folder is never pushed to the remote repository. ‘TODO’ .git .git The simplest way is to store the hooks in a normal folder in the repo and copy them over to on each user’s machine. However, we can’t rely on users to manually copy the scripts to the hooks folder. We need some scripts or tools that can install the hooks without any user intervention. Let’s assume the hooks are present in .git/hooks git-hooks. If you’re using Git version 2.9 or greater, you can simply run the below command to change the hooks folder to instead of git-hooks .git/hooks. git config core.hooksPath git-hooks You can also make above command to execute automatically by placing it in a setup file i.e Makefile, pom.xml , package.json etc. is one of the best options for installing git hooks in node project. However, if you are using an earlier version of git, you need to create a symbolic link by executing - Husky ln -s -f ../../git-hooks/pre-push .git/hooks/pre-push Conclusion Git Hooks are super cool and a great way to improve a team’s development workflow. The examples are just to show what the hooks are capable of. You can use these to check the lint issues or run unit tests before pushing the code or practically anything, you can think of. I am sure you guys can find a ton of use-cases to leverage the power of git hooks, if not using already. Hope you have learned something new !! Please clap 👏 👏 if you found this useful !! Thanks for reading.