check / check (push) Successful in 1m11s
The script wrote the hook to .git/hooks, which fails when .git is a file rather than a directory, as in a clone made with --separate-git-dir. It now asks git for the repository's own git directory with `git rev-parse --git-common-dir`, creates its hooks directory if missing, and writes the hook there. In an ordinary clone that is .git/hooks, so nothing moves. Before writing anything it stops with an error when its top directory is not the top of the checkout git finds, so a copy inside another repository cannot replace that repository's hook. git's core.hooksPath setting is not followed; where it is in force, git does not run the installed hook, as before. Model: opus-5-5
30 lines
1.1 KiB
Bash
Executable File
30 lines
1.1 KiB
Bash
Executable File
#!/bin/sh
|
|
# script/install-precommit: install the git pre-commit hook that runs
|
|
# script/precommit. Our own extension to scripts-to-rule-them-all.
|
|
set -eu
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
|
|
|
main() {
|
|
cd "$ROOT"
|
|
# Stop if this directory is not the top of its own git checkout, for
|
|
# example a copy inside another repository, whose hook must not be
|
|
# replaced.
|
|
if [ "$(git rev-parse --show-toplevel)" != "$ROOT" ]; then
|
|
echo "install-precommit: $ROOT is not the top of a git checkout" >&2
|
|
exit 1
|
|
fi
|
|
# Ask git for the repository's own git directory: .git is a file, not
|
|
# a directory, in some checkouts (for example a clone made with
|
|
# --separate-git-dir). core.hooksPath is deliberately not followed, so
|
|
# the hook is never written outside this repository.
|
|
hooks="$(git rev-parse --git-common-dir)/hooks"
|
|
mkdir -p "$hooks"
|
|
hook="$hooks/pre-commit"
|
|
printf '#!/bin/sh\nset -e\nscript/precommit\n' > "$hook"
|
|
chmod +x "$hook"
|
|
echo "pre-commit hook installed: runs script/precommit"
|
|
}
|
|
|
|
main "$@"
|