Skip to content

Latest commit

 

History

History
460 lines (329 loc) · 17.4 KB

README.md

File metadata and controls

460 lines (329 loc) · 17.4 KB

Financial Contributors on Open Collective Node.js CI

Git hooks made easy

Husky improves your commits and more 🐶 woof!

You can use it to lint your commit messages, run tests, lint code, etc... when you commit or push. Husky supports all Git hooks.

Announcement

👋 Read husky 5 announcement and see what's new

?> You're viewing documentation for husky v5, which is free to use in Open Source projects ❤️ and in early access for Sponsors 🎁. To use this new version at work, you can become a sponsor on GitHub Sponsors or Open Collective.

If you can't sponsor Husky, that's okay, husky v4 is free to use in any project.

Features

  • Zero dependencies
  • Lightweight (~0.02MB vs ~1MB for husky 4)
  • Fast (~0.01s vs ~0.5s for husky 4)
  • Supports macOS, Linux and Windows

Usage

Already using husky? See Migrate from 4 to 5.

Automatic (recommended)

# npm
npm install husky --save-dev && npx husky init

# yarn
yarn add husky --dev && yarn husky init

The command above will setup husky and create a sample pre-commit hook that you can edit. By default, it will run npm test when you commit.

To add another hook use husky add. For example:

# npm
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

# yarn
yarn husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

Manual

Install

  1. Install husky and pinst (optional)
# npm
npm install husky --save-dev
npm install pinst --save-dev # if your package is not private

# yarn
yarn add husky --dev
yarn add pinst --dev # if your package is not private
  1. Enable Git hooks
# npm
npx husky install

# yarn
yarn husky install
  1. To automatically have Git hooks enabled after install, edit package.json
// package.json
{
  "private": true,
  "scripts": {
    "postinstall": "husky install"
  }
}

!> if your package is not private and you're publishing it on a registry like npmjs.com, you need to disable postinstall script using pinst. Otherwise, postinstall will run when someone installs your package and result in an error.

// package.json
{
  "private": false,
  "scripts": {
    "postinstall": "husky install",
    "prepublishOnly": "pinst --disable",
    "postpublish": "pinst --enable"
  }
}

Add a hook

To add a hook, use husky add <file> [cmd] (don't forget to run husky install before).

npx husky add .husky/pre-commit "npm test"

Requires npm v7.4+ on Windows

Try to make a commit

git commit -m "Keep calm and commit"

If npm test command fails, your commit will be automatically aborted.

!> Using Yarn to run commands? There's an issue on Windows with Git Bash, see Yarn on Windows.

Uninstall

# npm
npm uninstall husky

# yarn
yarn remove husky && git config --unset core.hooksPath

Note: When uninstalling with npm, git config --unset core.hooksPath will be automatically run for you.

Recipes

Monorepo

It's recommended to add husky in root package.json. You can use tools like lerna and filters to only run scripts in packages that have been changed.

Custom directory

If you want to install husky in another directory, for example .config, you can pass it to install command. For example:

// package.json
{
  "scripts": {
    "postinstall": "husky install .config/husky"
  }
}

Another case you may be in is if your package.json file and .git directory are not at the same level. For example, project/.git and project/front/package.json.

By design, husky install must be run in the same directory as .git, but you can change directory during postinstall script and pass a subdirectory:

// package.json
{
  "scripts": {
    "postinstall": "cd .. && husky install front/.husky"
  }
}

In your hooks, you'll also need to change directory:

# .husky/pre-commit
# ...
cd front
npm test

Bypass hooks

You can bypass pre-commit and commit-msg hooks using Git -n/--no-verify option:

git commit -m "yolo!" --no-verify

For Git commands that don't have a --no-verify option, you can use HUSKY environment variable:

HUSKY=0 git push # yolo!

Disable hooks in CI

You can set HUSKY environment variable to 0 in your CI config file, to disable all hooks.

Alternatively, most Continuous Integration Servers set a CI environment variable. You can use it in your hooks to detect if it's running in a CI.

# .husky/pre-commit
# ...
[ -n "$CI" ] && exit 0

You can also use is-ci in your postinstall script to conditionnally install husky

npm install is-ci --save-dev
// package.json
{
  "scripts": {
    "postinstall": "is-ci || husky install"
  }
}

Test hooks

If you want to test a hook, you can add exit 1 at the end of the script to abort git command.

# .husky/pre-commit
# ...
exit 1 # Commit will be aborted

Git-flow

If using git-flow you need to ensure your git-flow hooks directory is set to use Husky's (.husky by default).

git config gitflow.path.hooks .husky

Note:

  • If you are configuring git-flow after you have installed Husky, the git-flow setup process will correctly suggest the .husky directory.
  • If you have set a custom directory for Husky you need to specify that (ex. git config gitflow.path.hooks .config/husky)

To revert the git-flow hooks directory back to its default you need to reset the config to point to the default Git hooks directory.

git config gitflow.path.hooks .git/hooks

FAQ

Does it work on Windows?

Yes. When you install Git on Windows, it comes with the necessary software to run shell scripts.

Troubleshoot

Command not found

If you're running Git from an app and the command can be found in your terminal, this means that the PATH in your app is different from your terminal.

You can echo $PATH in your terminal and configure your app to use the same value.

If you've installed your command using brew, see the Homebrew FAQ to make your command available to your app.

Finally, if you're using a script for managing versions like nvm, n, rbenv, pyenv, ... you can use ~/.huskyrc to load the necessary before running hooks.

For example, for nvm that would be:

# ~/.huskyrc
# This loads nvm.sh and sets the correct PATH before running hook
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

Hooks not running

Ensure that you don't have a typo in your filename. For example, precommit or pre-commit.sh are invalid names. See Git hooks documentation for valid names.

Verify hooks permissions, they should be executable. This is automatically set when using husky add command but you can run chmod +x .husky/<hookname> to fix that.

Check that your version of Git is greater than 2.9.

Yarn on Windows

Git hooks may fail when using Yarn on Windows with Git Bash (stdin is not a tty). If you have users on Windows, it's highly recommended to add the following workaround.

  1. Create .husky/common.sh:
command_exists () {
  command -v "$1" >/dev/null 2>&1
}

# Workaround for Windows 10, Git Bash and Yarn
if command_exists winpty && test -t 1; then
  exec < /dev/tty
fi
  1. Source it in in places where Yarn is used to run commands:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
. "$(dirname "$0")/common.sh"

yarn ...

Free for Open Source, early access for Sponsors

How it works?

  • If you have an Open Source project, you're free to install or upgrade husky to v5 ❤️
  • If you have a commercial project and are a Sponsor, you can start using v5 today at work 🎁

To acquire a proprietary-use license, simply go to GitHub Sponsors or Open Collective.

Breaking changes

Environment variables:

  • HUSKY_SKIP_HOOKS becomes HUSKY.
  • HUSKY_SKIP_INSTALL is removed.
  • HUSKY_GIT_PARAMS is removed. Instead Git parameters should be used directly in scripts (e.g. $1).
  • PATH for locally installed tools is not automatically set anymore. You'll need to use your package manager to run them.

Migrate from v4 to v5

husky-4-to-5 CLI

See husky-4-to-5 CLI to quickly migrate from v4 to v5.

Package scripts

If you were calling package.json scripts using npm or yarn, you can simply copy your commands:

// .huskyrc.json (v4)
{
  "hooks": {
    "pre-commit": "npm test && npm run foo"
  }
}
# .husky/pre-commit (v5)
# ...
npm test
npm run foo

Locally installed binaries

If you were calling directly locally installed binaries, you need to run them via your package manager:

// .huskyrc.json (v4)
{
  "hooks": {
    "pre-commit": "jest"
  }
}
# .husky/pre-commit (v5)
# ...
npx --no-install jest
yarn jest

HUSKY_GIT_PARAMS (i.e. commitlint, ...)

Previous HUSKY_GIT_PARAMS environment variable is replaced by native params $1, $2, etc.

// .huskyrc.json (v4)
{
  "hooks": {
    "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
  }
}
# .husky/commit-msg (v5)
# ...
npx --no-install commitlint --edit $1
# or
yarn commitlint --edit $1

Sponsors

Companies

Does your company use Husky? Ask your manager or marketing team if your company would be interested in supporting this project.

Individuals

Find Husky helpful? Become a backer and show your appreciation with a monthly donation on Open Collective. You can also tip with a one-time donation.

Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor Husky Sponsor

GitHub sponsors can be viewed on my profile. All past and current Open Collective sponsors can be viewed on Husky's Open Collective.

License

License Zero Parity 7.0.0 and MIT (contributions) with exception License Zero Patron 1.0.0.

👉 See the announcement for more details.