Get Started with Git Hooks and Husky
Tags: git, husky
Published: 2021-08-12 03:18:31

## What are Git Hooks?, How they work?, How can I use then? :confused:

Those are a few question I'm gonna try to answer in this post.

As you may know Git is a version control system and like many other control systems it has some predetermined custom scripts to run certain kind of operations, these are called hooks and they are divided into two categories.

## Client Side
This hooks are triggered by operations such as committing or merging, between this hooks we have `pre-commit`, `prepare-commit-msg`, `commit-msg` just to name a few.

## Server Side
This hooks run only on network operations such as receiving pushed commits, in this hooks you can find `pre-receive`, `update` and `post-receive`.

## Install Git Hooks
Hooks live inside the `.git/hooks` directory of every git repository. Git automatically populate this folder with some example scripts, if you navigate to the `.git/hooks` directory you will see the following files:

```shell
applypatch-msg.sample   fsmonitor-watchman.sample
pre-applypatch.sample   prepare-commit-msg.sample
pre-rebase.sample       update.sample
commit-msg.sample       post-update.sample
pre-commit.sample       pre-push.sample
pre-receive.sample
```
These are the most common hooks available,as you can see they all have a `.sample` extension, what this those is that it prevents them from executing by default, to "install" a hook all you need to do is remove the `.sample` extension.

## Hooks Scope
Hooks are local to any git repository, this means they are **not** copied into another repository when you run `git clone`.

This represents a big impact when you try to configure hooks for a team of developers, just the simple configuration can be tricky since you have to take into account that `.git/hooks` directory isn't clone with the rest of your project, nor is it under version control, a simple solution will be to place the hooks in the root of your project (above the .git directory).

## What Can You Use Hooks For
You can use hooks to do pretty much everything you want, for example let's say we are working with the `pre-commit` hook (this script runs every time you run the `git commit` before git ask the developer for a commit message). You can use this hook to inspect the snapshot is about to be committed, you may want to run some automated test to make sure the commit doesn't break any existing functionality.

## Husky
Now you might be wondering if there is a simple way to do all that, based on everything I told you you might think is not worth the effort since is way to complicated, well don't sweat it since husky is here to make your life more easy :dog: woof!

### Install Husky
In previous versions of husky (v4) all you need it to do was to add husky as a dev dependecy by running:

```shell
#NPM
npm install --save-dev husky

#Yarn
yarn add --dev husky
```

Then you need it to add the following inside your `package.json`

<code>
"husky": {
   "hooks": {
      "pre-commit": "echo ”[Husky] pre-commit”"
   }
}
</code>

Once that setup was complete you were ready to go. Since the release of version 6, things are a little different

#### Automatic (recommended)
```shell
#NPM
npx husky-init && npm install

#Yarn 1
npx husky-init && yarn

#Yarn 2
yarn dlx husky-init --yarn2 && yarn
```
This will create a directory in the root of your project called .husky, inside of it you will find the pre-commit hook with the instruction to run `npm test`, you can update that instructions to `yarn test` if you are using yarn.

What this will do is to run the test script "if you have any" before it even lets you create a commit message. Keep in mind that you inside the pre-commit hook you can run whatever you want, you can run a linter or anything that comes to your mind.

To add new hooks you can do it by using `husky add`

For example:
```shell
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
```

#### Manual
- Install
```shell
#NPM
npm install --save-dev husky

#Yarn
yarn add --dev husky
```
- Enable git hooks
```shell
npx husky install
```
- To automatically have then enabled after install you need to add the following script to your `package.json`
<code>
"prepare": "husky install"
</code>

> Yarn 2 does not support `prepare` lifecycle script, so you need to install husky differently

- To add or create a new hook you can use the following: `husky add <file> [cmd]`

  Example:
```shell
npx husky add .husky/pre-commit "npm test"
git add .husky/pre-commit
```

- Now if you try to commit your new changes, lets say for example `git commit -m "keep it clean"` the hook should trigger and if `npm test` fails, your commit will be automatically aborted.

## Bonus

If you are using **Yarn 2** the installation is a little different than with *npm* and *Yarn 1*, here are the steps you should follow when working with Yarn 2.

- Install Husky
```shell
yarn add husky --dev
yarn add pinst --dev # ONLY if your package is not private
```

- Enable Git Hooks
```shell
yarn husky install
```

- To automatically have then enabled after install, edit your `package.json`
```shell
// package.json
{
  "private": true, // ← your package is private, you only need postinstall
  "scripts": {
    "postinstall": "husky install"
  }
}
```

> If your package is not private, add the following instead
```shell
// package.json
{
  "private": false, // ← your package is public
  "scripts": {
    "postinstall": "husky install",
    "prepublishOnly": "pinst --disable",
    "postpublish": "pinst --enable"
  }
}
```

Keep Coding :computer:
Keep Learning :book:

Hope this can help you, and now you have a more clear understanding of what are Git Hooks, how they work and what is Husky :dog:

Here are some useful link you should check out

https://typicode.github.io/husky
https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
https://www.atlassian.com/git/tutorials/git-hooks
https://github.com/conventional-changelog/commitlint