Changelog¶
All notable changes to this project are documented here.
[3.1.0]¶
New Features¶
- Local override (
githooks.local.php): GitHooks looks for agithooks.local.phpfile alongsidegithooks.php. If found, its contents are merged over the main config usingarray_replace_recursive. Allows per-developer environment customization without modifying the shared config. Addgithooks.local.phpto.gitignore. See Docker & Local Override. executable-prefixoption: New option at global, flow, and job level. Prepends a command to all job executables (e.g.'docker exec -i app'). Per-job override with''ornullto opt out. Enables Docker, Laravel Sail, and remote environments from a single config. See Options: executable-prefix.- Extra arguments via
--forjobcommand:githooks job phpunit_all -- --filter=testFoopasses extra flags to the underlying tool. Enables dynamic execution from AI tools, scripts, or quick debugging without modifying configuration. Seegithooks job. - External documentation site: Full MkDocs Material site with getting started guide, configuration reference, CLI reference, tool docs, how-to guides, migration guides, and comparison page.
Bug Fixes¶
- Fix skipped job warnings not showing orange color in terminal output.
[3.0.0] - 2026-04-10¶
Breaking Changes¶
- PHP minimum raised to 7.4. Dropped support for PHP 7.0-7.3.
- SecurityChecker tool removed. Use a
customjob withcomposer auditas replacement. - New configuration format: hooks/flows/jobs. Replaces the previous
Options/Toolsformat. The old format still works but emits a deprecation warning. toolcommand deprecated. Replaced byflowandjobcommands. Will be removed in v4.0.- YAML configuration deprecated. PHP format is now the primary format. YAML still works but emits a deprecation warning. Will be removed in v4.0.
New Architecture — Hooks, Flows, Jobs¶
- Hooks: Map git events (
pre-commit,pre-push, etc.) to flows and jobs. Usescore.hooksPathwith a universal script instead of copying files to.git/hooks/. - Flows: Named groups of jobs with shared options (
fail-fast,processes). Reusable across hooks and directly executable from CLI/CI. - Jobs: Individual QA tasks with declarative configuration. Each job declares a
type(phpstan, phpcs, phpunit, custom, etc.) and its arguments.
New Commands¶
githooks flow <name>— Run a flow by name. Supports--fail-fast,--processes=N,--exclude-jobs,--only-jobs,--dry-run,--format=json|junit,--fast,--fast-branch,--monitor.githooks job <name>— Run a single job by name. Supports--dry-run,--format=json|junit,--fast,--fast-branch.githooks hook:run <event>— Run all flows/jobs associated with a git hook event (called by the universal hook script).githooks status— Show installed hooks, their sync state with config (synced/missing/orphan), and target flows/jobs.githooks system:info— Show detected CPUs and currentprocessesconfiguration with budget warning.githooks conf:migrate— Migrate v2 configuration to v3 format with automatic backup.githooks cache:clear— Clear cache files generated by QA tools. Accepts job names, flow names, or a mix.
Updated Commands¶
githooks hook— Now usescore.hooksPath+.githooks/directory instead of copying scripts to.git/hooks/.--legacyflag preserves old behavior (Git < 2.9).githooks hook:clean— Default now removes.githooks/+ unsetscore.hooksPath.--legacyflag removes individual hooks from.git/hooks/.githooks conf:init— Now supports--legacyflag to generate v2 format.githooks conf:check— Updated for v3: shows Options, Hooks, Flows, and Jobs tables with the full command each job will execute. Deep validation: verifies executables exist, paths are valid, and config files are accessible.
New Job Types¶
- Custom: Replaces the v2
scripttool. Supportsscriptkey (simple mode) and a new structured mode viaexecutablePath+paths+otherArguments. Structured mode enables--fastacceleration identical to standard tools.
Execution Modes and Structured Output¶
--format=jsonand--format=junit: Structured output forflowandjobcommands. JSON for machine-readable results; JUnit XML for CI test reporting.fast-branchexecution mode: New third mode alongsidefullandfast. Analyzes files that differ between the current branch and the main branch. Ideal for CI/CD. Non-accelerable jobs always run with full paths. Per-jobaccelerablekey overrides the default. Deleted files are excluded automatically.fast-branch-fallbackoption: Controls behavior whenfast-branchcannot compute the diff (e.g. shallow clone). Values:full(default) orfast.main-branchoption: Configure the main branch name forfast-branchdiff computation. Auto-detected if not specified.- Thread budget:
processesnow controls total CPU cores, not just parallel jobs. GitHooks distributes threads across jobs respecting each tool's capabilities (phpcs--parallel, parallel-lint-j, psalm--threads). PHPStan workers detected from.neonconfig. --monitorflag: Shows peak estimated thread usage after flow execution, with warning if budget was exceeded.- Job argument validation:
conf:checkandflow/jobcommands validate job configuration keys and types at parse time.
Developer Experience¶
--dry-runflag: Shows the exact shell command each job would execute without running anything. Works with all output formats —--format=jsonincludes acommandfield per job.--only-jobsflag: Inverse of--exclude-jobsfor theflowcommand. Run only the specified jobs:githooks flow qa --only-jobs=phpstan_src,phpmd_src.- Deep validation in
conf:check: Checks that executables exist, that configuredpathsare real directories, and that referenced config files are accessible. - Auto-detection of
executablePath: When omitted, GitHooks looks forvendor/bin/{tool}before falling back to system PATH.
Conditional Execution¶
exclude-files: Excludes staged files matching glob patterns from triggering execution. Always prevails overonly-files.exclude-on: Excludes branches matching glob patterns. Always prevails overonly-on.- Double-star (
**) glob support: File patterns now support**for recursive directory matching.src/**/*.phpmatches all PHP files undersrc/at any depth. hooks.commandconfig key: Customize the command used in generated hook scripts (e.g.'command' => 'php7.4 vendor/bin/githooks').