Skip to content

Commit 28351e7

Browse files
committed
fix(scripts): stop the pre-commit hook from blocking commits on older revisions
The installed hook exec'd scripts/preflight.sh unconditionally. That hook is a local, untracked artifact, so it survives a checkout of any commit that predates the script, and on such a commit exec failed with a bare "No such file or directory" — blocking the commit with nothing to act on. In this repository scripts/preflight.sh first appears at 8e12401, so every earlier commit is affected. The failure is also silent in a dangerous way: it swallowed a `git commit --amend`, so a commit-message rewrite reported as applied when it had not been, and had to be redone. The hook now checks the script is executable and exits 0 otherwise, so a revision without the pre-flight simply skips it. Normal operation is unchanged. Also honours core.hooksPath. git ignores .git/hooks entirely once that is set, so the hook was being written to a location that would never run while this script still reported success. No repository sets it today, so that part is latent.
1 parent 92d8597 commit 28351e7

1 file changed

Lines changed: 26 additions & 5 deletions

File tree

‎scripts/install-git-hooks.sh‎

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,42 @@
44
# Installs an optional pre-commit hook that runs scripts/preflight.sh so a
55
# broken import/lint is caught before the commit (and before a CI round-trip).
66
# Bypass a single commit with: git commit --no-verify
7+
#
8+
# Re-run this after pulling, and re-run it from the repository root. To remove
9+
# the hook, delete .git/hooks/pre-commit (or the core.hooksPath directory).
710
set -euo pipefail
811

912
cd "$(dirname "$0")/.."
1013

11-
HOOK=".git/hooks/pre-commit"
12-
if [ ! -d .git/hooks ]; then
13-
echo "install-git-hooks: .git/hooks not found (not a git repo?)" >&2
14-
exit 2
14+
# git ignores .git/hooks entirely once core.hooksPath is set, so a hook written
15+
# there would never run while this script still reported success.
16+
HOOKS_PATH="$(git config core.hooksPath || true)"
17+
if [ -n "$HOOKS_PATH" ]; then
18+
echo "install-git-hooks: core.hooksPath is set to '$HOOKS_PATH'." >&2
19+
echo "install-git-hooks: .git/hooks is ignored by git; writing the hook to" >&2
20+
echo " '$HOOKS_PATH/pre-commit' instead." >&2
21+
HOOK="$HOOKS_PATH/pre-commit"
22+
mkdir -p "$HOOKS_PATH"
23+
else
24+
HOOK=".git/hooks/pre-commit"
25+
if [ ! -d .git/hooks ]; then
26+
echo "install-git-hooks: .git/hooks not found (not a git repo?)" >&2
27+
exit 2
28+
fi
1529
fi
1630

1731
cat > "$HOOK" <<'HOOK_BODY'
1832
#!/usr/bin/env bash
1933
# Installed by scripts/install-git-hooks.sh — runs the local pre-flight.
2034
# Skip with: git commit --no-verify
21-
exec "$(git rev-parse --show-toplevel)/scripts/preflight.sh"
35+
#
36+
# The guard below matters on older revisions: this hook is a local, untracked
37+
# artifact, so it survives a checkout of a commit that predates
38+
# scripts/preflight.sh. Without the guard, exec fails with a bare
39+
# "No such file or directory" and blocks the commit with nothing to act on.
40+
PREFLIGHT="$(git rev-parse --show-toplevel)/scripts/preflight.sh"
41+
[ -x "$PREFLIGHT" ] || exit 0
42+
exec "$PREFLIGHT"
2243
HOOK_BODY
2344
chmod +x "$HOOK"
2445

0 commit comments

Comments
 (0)