lefthook pre-push lanes silently skip on explicit-refspec pushes
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
`lefthook`'s `pre-push` lanes silently skip on **explicit-refspec pushes** — `git push :` — because push files are derived from the checked-out HEAD's diff. A contributor pushing that way gets **zero** pre-push gates and a log that reads like normal operation.
## Reproduction
From a checkout where `HEAD` has no diff against `origin/main`:
```
git push refs/heads/some-branch:refs/heads/some-branch
```
Every lane reports `(skip) no matching push files` — including `branch-skew` and `push-head-scope`, which carry no `files:`/`glob:` of their own. Exit 0, push proceeds.
## Why this is worth fixing rather than documenting
`AGENTS.md` notes that non-HEAD ref pushes "rely on CI for their path-scoped checks", so the behaviour is known. The problem is the **signal**: the output is indistinguishable from a run where every lane genuinely had nothing to do. Someone pushing `branch:branch` — an ordinary thing to do — reasonably believes the hooks ran.
We hit this while pushing several branches by refspec and initially credited the hooks with checks they had not performed. Every "gates green" we reported came from running the gates explicitly; the hook contributed nothing.
## Suggested direction
Either make lanes without `files:`/`glob:` run unconditionally regardless of push shape, or emit a distinct non-skip message when the push shape means no lane can evaluate — so "nothing to check" and "cannot check" are distinguishable.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Contributor guide
Assessment
This issue has not been assessed yet.