Expand description
The two dispatchers.
They are NOT the same shape, and both shapes are load-bearing:
pre-commitruns its checks CONCURRENTLY and reports EVERY failure. Serial would be a visible slowdown on each commit; stopping at the first failure would hide the rest, so you’d fix one lint error, commit, and immediately meet the next.pre-pushruns them SERIALLY and stops at the FIRST failure, naming just that check. The steps are ordered and expensive (protected branch, then branch name, then rebase, then the whole test suite) and there is no point running tests after a rebase conflict.
Resist the tempting shared run_all helper — collapsing these is the
obvious way to silently lose the distinction. tests/dispatchers.rs pins
both.
Checks are FUNCTIONS in this binary, called directly. They used to be files:
.git/hooks/pre-commit-*, each an identical sh shim whose only job was to
re-exec this same binary and tell it its own name. One commit therefore cost
27 processes — a shim, the binary, then 13 more shims and 13 more binaries —
to do work the binary already had in a table.
Deleting that removed the filename glob (order was lexicographic, so a
rename could silently reorder a gate), the shebang emulation Windows needed
because it cannot execute a #! script, and the spawn plumbing under both.
Order is now a declared list in registry.
Functions§
- enter_
all_ files_ mode - Point every check at
git ls-filesinstead of the index. - pre_
commit - pre_
push - run_all
amont run— every applicable check, on demand.- run_
named amont run <check>— one check by name.Nonewhen there is no such check, which the caller turns into a usage error.