包详细信息

lefthook

evilmartians1.7mMIT1.11.13

Simple git hooks manager

git, hook, manager

自述文件

Build Status Coverage Status

Lefthook

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.

📖 Introduction post

Sponsored by Evil Martians

Install

With Go (>= 1.24):

go install github.com/evilmartians/lefthook@latest
  • or as a go tool
go get -tool github.com/evilmartians/lefthook

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:
  jobs:
    - name: lint frontend
      run: yarn eslint {staged_files}

    - name: lint backend
      run: bundle exec rubocop --force-exclusion {all_files}

    - name: stylelint frontend
      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:
  jobs:
    - name: lint backend
      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:
  jobs:
    - name: lint backend
      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:
  jobs:
    - script: "template_checker"
      runner: bash
  • Tags

    If you want to control a group of commands. docs
pre-push:
  jobs:
    - name: audit packages
      tags:
        - frontend
        - linters
      run: yarn lint

    - name: audit gems
      tags:
        - backend
        - security
      run: bundle audit
  • Support Docker

If you are in the Docker environment. docs

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

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

# lefthook-local.yml
pre-push:
  exclude_tags:
    - frontend
  jobs:
    - name: audit packages
      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:
  jobs:
    - run: bundle exec rubocop --force-exclusion --safe-auto-correct {staged_files}
    - 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

更新日志

Change log

1.11.13 (2025-05-16)

1.11.12 (2025-04-28)

  • feat: load from .config dir (#1017) by @mrexox
  • feat: complete all job names, recursively (#1015) by @scop
  • docs: update links to mise by @mrexox

1.11.11 (2025-04-21)

1.11.10 (2025-04-14)

1.11.9 (2025-04-11)

1.11.8 (2025-04-08)

1.11.7 (2025-04-07)

  • fix: avoid error logging when determining pre push files (#995) by @mrexox
  • docs: allow duplicate files in SUMMARY (#988) by @mrexox
  • fix: unquote paths to valid UTF-8 (#987) by @mrexox
  • packaging: aur fixes (#985) by @mrexox

1.11.6 (2025-03-31)

  • fix: print git errors (#984) by @mrexox
  • packaging: maintain lefthook-bin AUR package (#982) by @mrexox
  • chore: fancier logging (#983) by @mrexox
  • docs: remove a note about the difference for unix-like and windows by @mrexox

1.11.5 (2025-03-25)

1.11.4 (2025-03-24)

1.11.3 (2025-03-07)

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'