git-hooks
Installs packaged Fast Forward Git hooks.
Description
The git-hooks
command installs the hook templates maintained in
resources/git-hooks
into the repository. It:
- Copies hook files from a source directory to the target hooks directory
- Sets executable permissions on copied hooks
- Replaces drifted hooks defensively by removing the previous target before recopying it
Usage
cpx --skip-local "fast-forward/dev-tools:$DEV_TOOLS_VERSION" git-hooks
cpx --skip-local "fast-forward/dev-tools:$DEV_TOOLS_VERSION" git-hooks [options]
cpx --skip-local "fast-forward/dev-tools:$DEV_TOOLS_VERSION" git-hooks [options]
vendor/bin/dev-tools git-hooks [options]
Options
--source, -s(optional)- Path to the packaged Git hooks directory. Default:
resources/git-hooks. --target, -t(optional)- Path to the target Git hooks directory. Default:
.git/hooks. --no-overwrite- Do not overwrite existing hook files.
--dry-run- Preview managed Git hook drift without copying files.
--check- Exit with code
1when packaged Git hooks differ from the installed versions. --interactive- Prompt before replacing a drifted Git hook.
When a hook still cannot be rewritten because the target remains locked or
unwritable, the command logs a clear error for that hook, continues processing
the remaining hooks, and exits non-zero so dev-tools:sync
reports the hook
install problem clearly instead of aborting mid-copy.
--json- Emit a structured machine-readable payload instead of the normal terminal output.
--pretty-json- Emit the same structured payload with indentation for terminal inspection.
Examples
Install hooks with defaults:
cpx --skip-local "fast-forward/dev-tools:$DEV_TOOLS_VERSION" git-hooks
Install hooks without overwriting existing ones:
cpx --skip-local "fast-forward/dev-tools:$DEV_TOOLS_VERSION" git-hooks --no-overwrite
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success. Hooks installed successfully. |
| 1 | Failure. Drift detected in --check
mode or one or more hooks could
not be rewritten automatically. |
Preview safety
Missing targets are reported as planned creations. --dry-run
returns success
and --check
returns failure without creating files or parent directories,
including when overwrite or interactive options are also supplied. When both
preview flags are supplied, --check
determines the failure status. Existing
targets are compared without replacement or permission changes.
Runtime and durable configuration
Hooks prefer vendor/bin/grumphp
or vendor/bin/grumphp.phar
; otherwise
they run cpx --skip-local phpro/grumphp-shim:2.26.0 grumphp
. The explicit
binary name avoids an interactive choice between grumphp
and grumphp.phar
.
CPX must be available
when no local executable exists. GrumPHP is not a DevTools runtime dependency.
Explicit dev-tools:sync
copies a missing grumphp.yml
into the consumer
root. Local overrides remain authoritative; hooks do not persist temporary
runtime/cache paths.
The packaged GrumPHP configuration allows 600 seconds per process so its
composer dev-tools
task can complete the full coverage and reports pipeline.