Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@arkweid/lefthook

evilmartians49.1kMITdeprecated0.7.7

@arkweid/lefthook has been renamed to @evilmartians/lefthook, please upgrade to it. You also can use @evilmartians/lefthook-installer

Simple git hooks manager

git, hook, manager

readme

Build Status

Lefthook

The fastest polyglot Git hooks manager out there

Fast and powerful Git hooks manager for Node.js, Ruby or any other type of projects.

  • Fast. It is written in Go. Can run commands in parallel.
  • Powerful. With a few lines in the config you can check only the changed files on pre-push hook.
  • Simple. It is single dependency-free binary which can work in any environment.

📖 Read the introduction post

# On `git push` lefthook will run spelling and links check for all of the changed files
pre-push:
  parallel: true
  commands:
    spelling:
      files: git diff --name-only HEAD @{push}
      glob: "*.md"
      run: npx yaspeller {files}
    check-links:
      files: git diff --name-only HEAD @{push}
      glob: "*.md"
      run: npx markdown-link-check {files}
Sponsored by Evil Martians

Usage

Choose your environment:

Then you can find all Lefthook features in the full guide and explore wiki.


Why Lefthook

  • Parallel execution

    If you want more speed. Example
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.
pre-commit:
  commands:
    backend-linter:
      glob: "*.rb" # glob filter
      exclude: "application.rb|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. Example.

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

    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
  • Support Docker

If you are in the Docker environment. Example.

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. Description.

# 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

Table of contents:

Guides

Migrate from

Examples

Benchmarks

Comparison list

Articles

changelog

Change log

1.11.2 (2025-02-26)

  • fix: do not inherit envs in remote Git commands (#963) by @mrexox

1.11.1 (2025-02-25)

1.11.0 (2025-02-23)

1.10.11 (2025-02-21)

  • deps: bump github.com/spf13/cobra from 1.8.1 to 1.9.1 (#952) (#958) by @mrexox
  • fix: add $schema property (#942) by @mst-mkt
  • deps: bump github.com/briandowns/spinner from 1.23.1 to 1.23.2 (#935) (#940) by @mrexox

1.10.10 (2025-01-21)

  • feat: allow providing a list of globs (#937) by @mrexox
  • fix: properly inherit exclude options when not overwritten (#936) by @mrexox

1.10.9 (2025-01-20)

  • fix: make uninstall --remove-configs description more accurate (#934) by @scop

1.10.8 (2025-01-17)

  • feat: add custom plain templates (#930) by @mrexox
  • fix: unique names for nested operations (#931) by @mrexox

1.10.7 (2025-01-15)

  • fix: use lefthook option in ghost hook too (#929) by @mrexox
  • feat: add schema.json to npm packages (#928) by @mrexox
  • fix: increase timeout for self-update to 2 mins by @mrexox

1.10.5 (2025-01-14)

  • feat: add lefthook option for custom path or command (#927) by @mrexox
  • chore: update config template with new jobs by @mrexox

1.10.4 (2025-01-13)

  • fix: avoid skipping pre commit when deleted files staged (#925) by @mrexox
  • fix: use roots from jobs for possible npm package location (#924) by @mrexox
  • deps: January 2025 (#926) by @mrexox

1.10.3 (2025-01-10)

1.10.2 (2025-01-10)

  • feat: add validate command (#915) by @mrexox
  • feat: inherit exclude option in groups (#916) by @mrexox
  • chore: auto generate json schema (#914) by @mrexox
  • feat: run --jobs completion (#913) by @scop
  • ci: add gzipped linux aarch64 binary to release artifacts (#908) by @mrexox -

    1.10.1 (2024-12-26)

  • feat: add ability to specify job names for command run (#904) by @mrexox

  • ci: add linux aarch64 binary to release (#903) by @mrexox
  • ci: fix aur build (#905) by @mrexox

1.10.0 (2024-12-19)

1.9.3 (2024-12-18)

1.9.2 (2024-12-12)

  • fix: use correct remote scripts folder (#891) by @mrexox

1.9.1 (2024-12-12)

1.9.0 (2024-12-06)

1.8.5 (2024-12-02)

  • ci: automate publishing to cloudsmith (#875) by @mrexox
  • feat: add option to skip running LFS hooks (#879) by @zachah

1.8.4 (2024-11-18)

1.8.3 (2024-11-18)

  • fix: use absolute paths when cloning remotes (#873) by @mrexox

1.8.2 (2024-10-29)

1.8.1 (2024-10-23)

  • chore: bump Go to 1.23 (#856) by Valentin Kiselev
  • fix: skip git lfs hook when calling manually (#855) by Valentin Kiselev

1.8.0 (2024-10-22)

  • fix: [breaking] don't auto-install lefthook with npx if not found (#602) by @anthony-hayes
  • fix: [breaking] execute files command within configured root (#607) by @mrexox
  • fix: calculate hashsum of the full config (#854) by @mrexox
  • feat: support globs in extends (#853) by @mrexox
  • docs: simplify configuration docs (#851) by @mrexox

1.7.22 (2024-10-18)

1.7.21 (2024-10-17)

1.7.19 and 1.7.20 – failed to build

1.7.18 (2024-09-30)

1.7.17 (2024-09-26)

  • feat: skip LFS hooks when pre-push hook is skipped (#818) by @zachahn

1.7.16 (2024-09-23)

1.7.15 (2024-09-02)

1.7.14 (2024-08-17)

Fix lefthook NPM package to include OpenBSD package as optional dependency.

1.7.13 (2024-08-16)

1.7.12 (2024-08-09)

1.7.11 (2024-07-29)

1.7.10 (2024-07-29)

  • deps: July 2024 (#795) by @mrexox
  • packaging(npm): try direct reference for lefthook executable (#794) by @mrexox

1.7.9 (2024-07-26)

  • fix: typo CGO_ENABLED instead of GCO_ENABLED (#791) by @mrexox

1.7.8 (2024-07-26)

1.7.7 (2024-07-24)

1.7.6 (2024-07-24)

1.7.5 (2024-07-22)

1.7.4 (2024-07-19)

1.7.3 (2024-07-18)

1.7.2 (2024-07-11)

  • fix: add missing sub directory in hook template (#768) by @nikeee

1.7.1 (2024-07-08)

  • fix: use correct extension in hook.tmpl (#767) by @apfohl

1.7.0 (2024-07-08)

1.6.18 (2024-06-21)

  • fix: allow multiple levels of extends (#755) by @mrexox

1.6.17 (2024-06-20)

  • fix: apply local extends only if they are present (#754) by @mrexox
  • chore: setting proper error message for missing lefthook file (#748) by @Cadienvan

1.6.16 (2024-06-13)

  • fix: skip overwriting hooks when fetching data from remotes (#745) by @mrexox
  • fix: fetch remotes only for non ghost hooks (#744) by @mrexox

1.6.15 (2024-06-03)

  • feat: add refetch option to remotes config (#739) by @mrexox
  • deps: June, 3, lipgloss (0.11.0) and viper (1.19.0) (#742) by @mrexox
  • chore: enable copyloopvar, intrange, and prealloc (#740) by @scop
  • perf: delay git and uname commands in hook scripts until needed (#737) by @scop
  • chore: refactor commands interfaces (#735) by @mrexox
  • chore: upgrade to 1.59.0 (#738) by @scop

1.6.14 (2024-05-30)

1.6.13 (2024-05-27)

1.6.12 (2024-05-17)

  • fix: more verbose error on versions mismatch (#721) by @mrexox
  • fix: enable interactive scripts (#720) by @mrexox

1.6.11 (2024-05-13)

  • feat: add run --no-auto-install flag (#716) by @mrexox
  • fix: add --porcelain to git status --short (#711) by @110y
  • chore: bump go to 1.22 (#701) by @mrexox

1.6.10 (2024-04-10)

1.6.9 (2024-04-09)

  • fix: enable interactive inputs for windows (#696) by @mrexox
  • fix: add batching to implicit commands (#695) by @mrexox
  • fix: command argument count validations (#694) by @scop
  • fix: re-download remotes when called install with -f (#692) by @mrexox
  • chore: remove redundant parallelisation (#690) by @mrexox
  • chore: refactor Result handling (#689) by @mrexox

1.6.8 (2024-04-02)

1.6.7 (2024-03-15)

  • fix: don't apply empty patch files on pre-commit hook (#676) by @mrexox
  • docs: allow only comma divided tags (#675) by @mrexox

1.6.6 (2024-03-14)

1.6.5 (2024-03-04)

1.6.4 (2024-02-28)

1.6.3 (2024-02-27)

1.6.2 (2024-02-26)

  • fix: respect roots in commands for npm packages (#616) by @mrexox
  • fix: don't capture STDIN without interactive or use_stdin options (#638) by @technicalpickles
  • fix: handle LEFTHOOK_QUIET when there is no skip_output in config by @prog-supdex
  • docs: add stage_fixed to the examples by @mrexxo
  • docs: clarify the difference between piped and parallel options by @mrexox

1.6.1 (2024-01-24)

  • fix: files from stdin only null separated (#615) by @mrexox
  • docs: add a new article link by @mrexox

1.6.0 (2024-01-22)

1.5.7 (2024-01-17)

1.5.6 (2024-01-12)

  • feat: shell completion improvements (#577) by @scop
  • fix: safe execute git commands without sh wrapper (#606) by @mrexox
  • fix: use lefthook package with npx (#604) by @mrexox
  • feat: allow setting a bool value for skip_output (#601) by @nsklyarov
  • docs: update exception case about interactive option by @mrexox

1.5.5 (2023-11-30)

1.5.4 (2023-11-27)

  • chore: add typos fixer by @mrexox
  • fix: drop new argument for git diff compatibility (#586) by @mrexox

1.5.3 (2023-11-22)

  • fix: don't check checksum file when explicitly calling lefthook install (#572) by @mrexox
  • chore: skip summary separator if nothing is printed (#575) by @mrexox
  • docs: update info about root option by @mrexox

1.5.2 (2023-10-9)

  • fix: correctly sort alphanumeric commands (#562) by @mrexox

1.5.1 (2023-10-6)

  • feat: add force flag to run command (#561) by @mrexox
  • fix: do not enable export when sourcing rc file (#553) by @hyperupcall
  • chore: wrap shell args in quotes for consistency by @mrexox
  • docs: add a note that files template supports directories by @mrexox
  • feat: initial support for Swift Plugins (#556) by @csjones

1.5.0 (2023-09-21)

1.4.11 (2023-09-13)

  • docs: update docs and readme with tl;dr instructions (#548) by @mrexox
  • fix: add use_stdin option for just reading from stdin (#547) by @mrexox
  • chore: refactor commands passing (#546) by @mrexox
  • fix: fail on non existing hook name (#545) by @mrexox

1.4.10 (2023-09-04)

  • fix: split command with file templates into chunks (#541) by @mrexox
  • chore: add git-cliff config for easier changelog generation by @mrexox
  • fix: allow empty staged files diffs (#543) by @mrexox

1.4.9 (2023-08-15)

1.4.8 (2023-07-31)

1.4.7 (2023-07-24)

1.4.6 (2023-07-18)

  • fix: do not print extraneous newlines when executionInfo output is hidden (#519) by @hyperupcall
  • fix: uninstall all possible formats (#523) by @mrexox
  • fix: LEFTHOOK_VERBOSE properly overrides --verbose flag (#521) by @hyperupcall
  • feat: support .lefthook.yml and .lefthook-local.yml (#520) by @hyperupcall

1.4.5 (2023-07-12)

1.4.4 (2023-07-10)

  • fix: don't render bold ANSI sequence when colors are disabled (#515) by @adam12
  • deps: July 2023 (#514) by @mrexox

1.4.3 (2023-06-19)

1.4.2 (2023-06-13)

1.4.1 (2023-05-22)

1.4.0 (2023-05-18)

1.3.13 (2023-05-11)

1.3.12 (2023-04-28)

  • fix: allow skipping execution_out with interactive mode (#476) by @mrexox

1.3.11 (2023-04-27)

  • feat: add execution_out to skip output settings (#475) by @mrexox
  • chore: add debug logs when hook is skipped (#474) by @mrexox

1.3.10

1.3.9 (2023-04-04)

  • feat: allow extra hooks in local config (#462) by @fabn
  • feat: pass numeric placeholders to files command (#461) by @fabn

1.3.8 (2023-03-23)

  • fix: make hook template compatible with shells without source command (#458) by @mdesantis

1.3.7 (2023-03-20)

  • fix: allow globs in skip option (#457) by @mrexox
  • deps: dependencies update (March 2023) (#455) by @mrexox
  • fix: don't fail on missing config file (#450) by @mrexox

1.3.6 (2023-03-16)

  • fix: stage fixed when root specified (#449) by @mrexox
  • feat: implitic skip on missing files for pre-commit and pre-push hooks (#448) by @mrexox

1.3.5 (2023-03-15)

1.3.4 (2023-03-13)

  • fix: don't extra extend config if lefthook-local.yml is missing (#444) by @mrexox

1.3.3 (2023-03-01)

1.3.2 (2023-02-27)

1.3.1 (2023-02-27)

  • fix: Force creation of git hooks folder (#434) by @mrexox

1.3.0 (2023-02-22)

  • fix: Use correct branch for {push_files} template (#429) by @mrexox
  • feature: Skip unstaged changes for pre-commit hook (#402) by @mrexox

1.2.9 (2023-02-13)

1.2.8 (2023-01-23)

  • fix: Don't join info path with root (#418) by @mrexox

1.2.7 (2023-01-10)

1.2.6 (2022-12-14)

1.2.5 (2022-12-13)

1.2.4 (2022-12-05)

1.2.3 (2022-11-30)

1.2.2 (2022-11-23)

1.2.1 (2022-11-17)

1.2.0 (2022-11-7)

1.1.4 (2022-11-1)

1.1.3 (2022-10-15)

1.1.2 (2022-10-10)

1.1.1 (2022-08-22)

1.1.0 (2022-08-13)

1.0.5 (2022-07-19)

1.0.4 (2022-06-27)

1.0.3 (2022-06-25)

  • Fix NPM package
  • Update email information

1.0.2 (2022-06-24)

1.0.1 (2022-06-20) Ruby gem and NPM package fix

  • Fix folders structure for [@evilmartians](https://github.com/evilmartians)/lefthook and [@evilmartians](https://github.com/evilmartians)/lefthook-installer packages
  • Fix folders structure for lefthook gem

1.0.0 (2022-06-19)

0.8.0 (2022-06-07)

0.7.7 (2021-10-02)

0.7.6 (2021-06-02)

  • Fix lefthook binary extension on Windows. @aminya
  • PR #193 Fix path for searching npm-installed binary when in worktree. @Envek
  • NPM, RPM, and DEB packaging fixes. @Envek

0.7.5 (2021-05-14)

0.7.4 (2021-04-30)

0.7.3 (2021-04-23)

  • PR Package versions for all architectures (x86_64, ARM64, x86) into Ruby gem and NPM package @Envek
  • PR Fix golang 15+ build @skryukov

0.7.2 (2020-02-02)

0.7.1 (2020-02-02)

  • PR Fix sh dependency on windows when executing git. Thanks @lionskape

  • PR Add possibility for using yaml and yml extension for config. Thanks @rbUUbr

0.7.0 (2019-12-14)

  • PR Support relative roots for monorepos. Thanks @jsmestad

0.6.7 (2019-12-14)

0.6.6 (2019-12-03)

  • PR Use eval instead of exec; Enable tty for the shell. Thanks @ssnickolay

0.6.5 (2019-11-15)

  • PR Add support for git-worktree. Thanks @f440

  • Commit Commands and Scripts now can catch Stdin

  • Commit Add partial support for monorepos and command execution not from project root

0.6.4 (2019-11-08)

  • PR Fix return value from shell exit. Thanks @HaiD84

  • PR Support postinstall script for npm installation for monorepos. Thanks @sHooKDT

  • PR Now relative path to scripts supported. Thanks @AlexeyMatskevich

  • Commit Option extends for top level config added. Now you can merge some settings from different places:

    extends: $HOME/work/lefthook-extend.yml
  • Commit Add examples to generated lefthook.yml

0.6.3 (2019-07-15)

  • Commit Add -a means aggressive strategy for install command

    lefthook install -a # clear .git/hooks dir and reinstall lefthook hooks
  • Commit Add Lefthook version indicator for commands and script execution

  • Commit Remove npx as dependency from node wrapper

Now we will call directly binary from ./node_modules

  • Commit Add -f means force strategy for install command
lefthook install -f # reinstall lefthook hooks without sync info check
  • PR #27 Move LEFTHOOK env check in hooks files

Now if LEFTHOOK=0 we will not call the binary file

Add shortcut {push_files}

pre-commit:
  commands:
    rubocop:
      run: rubocop {push_files}

It same as:

pre-commit:
  commands:
    rubocop:
      files: git diff --name-only HEAD @{push} || git diff --name-only HEAD master
      run: rubocop {push_files}
  • Commit Add min_version option

You can mark your config for minimum Lefthook version:

min_version: 0.6.1

0.6.0 (2019-07-10)

  • PR #24 Wrap run command in shell context.

Now in run option available sh syntax.

pre-commit:
  commands:
    bashed:
      run: rubocop -a && git add

Will be executed in this way:

sh -c "rubocop -a && git add"
  • PR #23 Search Lefthook in Gemfile.

Now it's possible to use Lefthook from Gemfile.

# Gemfile

gem 'lefthook'