Skip to content

evilmartians/lefthook

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

62ab064 · Jan 15, 2025
Dec 23, 2024
Jan 10, 2025
Jan 14, 2025
Oct 28, 2024
Jan 14, 2025
Jan 15, 2025
Jan 14, 2025
Jan 15, 2025
Dec 19, 2024
Dec 27, 2024
Jan 14, 2025
Jan 14, 2025
Oct 23, 2024
Feb 5, 2019
Jan 9, 2025
Jan 10, 2025
Jul 7, 2022
Dec 19, 2024
Sep 4, 2023
Jan 13, 2025
Jan 13, 2025
May 23, 2023
Aug 5, 2019
Aug 6, 2019
May 23, 2023
Jan 14, 2025
Feb 25, 2024

Repository files navigation

Build Status Coverage Status

Lefthook

The fastest polyglot Git hooks manager out there

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

  • Fast. It is written in Go. Can run commands in parallel.
  • Powerful. It allows to control execution and files you pass to your commands.
  • Simple. It is single dependency-free binary which can work in any environment.

📖 Read the introduction post

📖 Read the documentation

Sponsored by Evil Martians

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

  • Configuration for lefthook.yml config options.
  • Usage for lefthook CLI options, supported ENVs, and usage tips.
  • Discussions for questions, ideas, suggestions.

Why Lefthook

  • Parallel execution

Gives you more speed. docs

pre-push:
  parallel: true
  • Flexible list of files

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}
  • Glob and regexp filters

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}
  • Execute in sub-directory

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}
  • Run scripts

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

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

If you want to control a group of commands. docs

pre-push:
  commands:
    packages-audit:
      tags:
        - frontend
        - linters
      run: yarn lint
    gems-audit:
      tags:
        - backend
        - security
      run: bundle audit
  • Support Docker

If you are in the Docker environment. docs

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

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

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

If you want to run hooks group directly.

$ lefthook run pre-commit
  • Your own tasks

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
  • Control output

You can control what lefthook prints with output option.

output:
  - execution
  - failure

Guides

Examples

Check examples

Articles