Home

Awesome

Build Status Coverage Status

Lefthook

The fastest polyglot Git hooks manager out there

<img align="right" width="147" height="100" title="Lefthook logo" src="./logo_sign.svg">

A Git hooks manager for Node.js, Ruby, Python and many other types of projects.

📖 Read the introduction post

<a href="https://evilmartians.com/?utm_source=lefthook"> <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>

Install

With Go (>= 1.23):

go install github.com/evilmartians/lefthook@latest

With NPM:

npm install lefthook --save-dev

For Ruby:

gem install lefthook

For Python:

pip install lefthook

Installation guide with more ways to install lefthook: apt, brew, winget, and others.

Usage

Configure your hooks, install them once and forget about it: rely on the magic underneath.

TL;DR

# Configure your hooks
vim lefthook.yml

# Install them to the git project
lefthook install

# Enjoy your work with git
git add -A && git commit -m '...'

More details

<!-- - [**Wiki**](https://github.com/evilmartians/lefthook/wiki) for guides, examples, and benchmarks. -->

Why Lefthook

Gives you more speed. Example

pre-push:
  parallel: true

If you want your own list. Custom and prebuilt examples.

pre-commit:
  commands:
    frontend-linter:
      run: yarn eslint {staged_files}
    backend-linter:
      run: bundle exec rubocop --force-exclusion {all_files}
    frontend-style:
      files: git diff --name-only HEAD @{push}
      run: yarn stylelint {files}

If you want to filter list of files. You could find more glob pattern examples here.

pre-commit:
  commands:
    backend-linter:
      glob: "*.rb" # glob filter
      exclude: '(^|/)(application|routes)\.rb$' # regexp filter
      run: bundle exec rubocop --force-exclusion {all_files}

If you want to execute the commands in a relative path

pre-commit:
  commands:
    backend-linter:
      root: "api/" # Careful to have only trailing slash
      glob: "*.rb" # glob filter
      run: bundle exec rubocop {all_files}

If oneline commands are not enough, you can execute files. Example.

commit-msg:
  scripts:
    "template_checker":
      runner: bash

If you want to control a group of commands. Example.

pre-push:
  commands:
    packages-audit:
      tags: frontend security
      run: yarn audit
    gems-audit:
      tags: backend security
      run: bundle audit

If you are in the Docker environment. Example.

pre-commit:
  scripts:
    "good_job.js":
      runner: docker run -it --rm <container_id_or_name> {cmd}

If you a frontend/backend developer and want to skip unnecessary commands or override something into Docker. Description.

# lefthook-local.yml
pre-push:
  exclude_tags:
    - frontend
  commands:
    packages-audit:
      skip: true

If you want to run hooks group directly.

$ lefthook run pre-commit

If you want to run specific group of commands directly.

fixer:
  commands:
    ruby-fixer:
      run: bundle exec rubocop --force-exclusion --safe-auto-correct {staged_files}
    js-fixer:
      run: yarn eslint --fix {staged_files}
$ lefthook run fixer

If you don't want to see supporting information:

skip_output:
  - meta #(version and which hook running)
  - success #(output from runners with exit code 0)

Guides

<!-- * [Troubleshooting](https://github.com/evilmartians/lefthook/wiki/Troubleshooting) --> <!-- ### Migrate from --> <!-- * [Husky](https://github.com/evilmartians/lefthook/wiki/Migration-from-husky) --> <!-- * [Husky and lint-staged](https://github.com/evilmartians/lefthook/wiki/Migration-from-husky-with-lint-staged) --> <!-- * [Overcommit](https://github.com/evilmartians/lefthook/wiki/Migration-from-overcommit) -->

Examples

<!-- ### Benchmarks --> <!-- * [vs Overcommit](https://github.com/evilmartians/lefthook/wiki/Benchmark-lefthook-vs-overcommit) --> <!-- * [vs pre-commit](https://github.com/evilmartians/lefthook/wiki/Benchmark-lefthook-vs-pre-commit) --> <!-- ### Comparison list --> <!-- * [vs Overcommit, Husky, pre-commit](https://github.com/evilmartians/lefthook/wiki/Comparison-with-other-solutions) -->

Articles