This lesson is for PRO members.

Unlock this lesson NOW!
Already subscribed? sign in

Practical Git: Run scripts on git events with git hooks

2:58 Tools lesson by

Git lets us run scripts on git events like pre-commit, pre-rebase, post-commit, post-merge, post-checkout, etc. You can do this by adding an executable file to the ./git/hooks directory which has a name matching the git hook name. In this lesson, we walk through this process by setting up a pre-commit hook which runs our npm test and npm run lint npm scripts to ensure we don't have any failing tests or lint errors before committing.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

Git lets us run scripts on git events like pre-commit, pre-rebase, post-commit, post-merge, post-checkout, etc. You can do this by adding an executable file to the ./git/hooks directory which has a name matching the git hook name. In this lesson, we walk through this process by setting up a pre-commit hook which runs our npm test and npm run lint npm scripts to ensure we don't have any failing tests or lint errors before committing.

Avatar
Meysam

Great tip! I did not know this

In reply to egghead.io

In our command line, we're going to set up a directory called Utility Functions which is a git-repository. If we take a look inside of our .git folder in our git-repo, we can see all of its folders and files.

One of these is the Hooks folder. Let's take a look at what's inside the Hooks folder.

By default, you can see that git provides a whole bunch of .sample files. Each of these files in your Hooks directory is a script that matches a git hook name.

For example, this pre-rebase script would be fired before every rebase in your repo. Now these don't run by default because they have this .sample extension. But if you were to remove the .sample and only have a file with just the hook name, git would automatically run that hook based on the name.

For our project, we want to automatically run our tests and our linting before every commit. Inside of our Hooks folder, let's make a new pre-commit script. Now let's open up this file in our code editor.

On the first line of our script file, we need to tell the shell which interpreter to use to execute the file. For this project, let's use bash. We do that by doing the number symbol, then explanation point, then bin/bash.

Now we could run anything here in this script that we want to execute before a commit. In the case of this project, we've defined some npm-script in our package.json and we'd like to run our test script as well as our lint script before each commit to insure that we don't have any broken tests or lint errors.

Now that we have script written out, we need to make sure that it's executable by our system. Let's go back to our command line and let's run chmod which stands for change mode and will let us change the permissions of a file. We need to pass it the plus x option which means we want to make a file executable as a program, and then we provide the path to file, which in this case is hooks and then pre-commit.

If we run that command, our pre-commit script is now executable. Now back in the root of our project, let's try to make a commit that has a broken test and lint errors.

Now when I run this commit, our pre-commit script is executed and we see that we have a broken test and that our commit did not go through. I've fixed the broken test, but there's still the lint error. Let's try to commit again.

Now our tests have passed, but our linting errors are being shown. I've fixed the lint errors. Let's commit again.

Now if we run git status, we can see that git has ran our pre-commit hook successfully and has allowed our commit to go through. One thing to know is that when you manually add a git hook inside of the Hooks folder in our .git folder that hook is only accessible locally on your machine.

If you'd like your hooks to be available in the remote repo for all people working on your project, you'll either need to write a script to copy it with something like npm-scripts or use a prebuilt tool.

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?