Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .githooks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,16 @@ Owned concerns:

- fast staged local/offline checks
- structure + style + staged static test validations
- scoped basic test lane only; repo-wide governance/unit suites stay out of pre-commit
- staged generator sync for managed artifacts
- reuses cached pass results when the staged snapshot and hook/test inputs are unchanged
- runtime budget enforcement (default: `<= 60s`)

Install behavior:

- configures worktree-local `core.hooksPath=.githooks`
- runs hooks directly from tracked repo files instead of copying stale hook files into `.git/hooks`

Out-of-scope concerns:

- browser sweeps
Expand Down
67 changes: 38 additions & 29 deletions .githooks/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,54 +3,63 @@
# @category utility
# @purpose tooling:dev-tools
# @scope .githooks
# @owner docs
# @domain docs
# @needs E-C6, F-C1
# @purpose-statement Installs git hooks by setting core.hooksPath to .githooks/
# @purpose-statement Installs git hooks by routing this worktree to .githooks via worktree-local core.hooksPath
# @pipeline manual — developer tool
# @usage bash .githooks/install.sh [flags]
# Install git hooks

# Support both regular repos and worktrees
GIT_COMMON_DIR=$(git rev-parse --git-common-dir 2>/dev/null)
if [ -z "$GIT_COMMON_DIR" ] || [ "$GIT_COMMON_DIR" = "--git-common-dir" ]; then
GIT_COMMON_DIR=".git"
fi
HOOKS_DIR="$GIT_COMMON_DIR/hooks"
SOURCE_DIR=".githooks"
set -euo pipefail

REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
SOURCE_DIR="$REPO_ROOT/.githooks"

cd "$REPO_ROOT"

if [ ! -d "$HOOKS_DIR" ]; then
echo "Error: hooks directory not found at $HOOKS_DIR"
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "Error: this command must run inside a git worktree."
exit 1
fi

if [ ! -d "$SOURCE_DIR" ]; then
echo "Error: .githooks directory not found. Are you in the repository root?"
echo "Error: .githooks directory not found at $SOURCE_DIR"
exit 1
fi

if [ ! -f "$SOURCE_DIR/pre-commit" ] || [ ! -f "$SOURCE_DIR/pre-push" ]; then
echo "Error: required hook entrypoints are missing from $SOURCE_DIR"
exit 1
fi

echo "Installing git hooks..."
echo "Installing git hooks for this worktree..."

# Install pre-commit hook
if [ -f "$SOURCE_DIR/pre-commit" ]; then
cp "$SOURCE_DIR/pre-commit" "$HOOKS_DIR/pre-commit"
chmod +x "$HOOKS_DIR/pre-commit"
echo "✓ Installed pre-commit hook"
else
echo "✗ pre-commit hook not found in $SOURCE_DIR"
git config extensions.worktreeConfig true

SHARED_HOOKS_PATH=$(git config --local --get-all core.hooksPath 2>/dev/null || true)
if [ -n "$SHARED_HOOKS_PATH" ]; then
git config --local --unset-all core.hooksPath || true
echo "✓ Cleared shared core.hooksPath override"
fi

# Install pre-push hook
if [ -f "$SOURCE_DIR/pre-push" ]; then
cp "$SOURCE_DIR/pre-push" "$HOOKS_DIR/pre-push"
chmod +x "$HOOKS_DIR/pre-push"
echo "✓ Installed pre-push hook"
else
echo "✗ pre-push hook not found in $SOURCE_DIR"
git config --worktree core.hooksPath .githooks
chmod +x "$SOURCE_DIR/pre-commit" "$SOURCE_DIR/pre-push"

RESOLVED_HOOKS_PATH=$(git config --worktree --path --get core.hooksPath 2>/dev/null || true)
if [ -z "$RESOLVED_HOOKS_PATH" ]; then
echo "Error: failed to resolve worktree-local core.hooksPath"
exit 1
fi
if [[ "$RESOLVED_HOOKS_PATH" != /* ]]; then
RESOLVED_HOOKS_PATH="$REPO_ROOT/$RESOLVED_HOOKS_PATH"
fi

echo "✓ Using worktree-local core.hooksPath: $RESOLVED_HOOKS_PATH"
echo "✓ Hook entrypoints are executable"

echo ""
echo "Git hooks installed successfully!"
echo ""
echo "The pre-commit hook will now check for style guide violations."
echo "The pre-push hook will enforce codex task contracts on codex/* branches."
echo "The pre-commit hook now runs directly from .githooks/pre-commit."
echo "The pre-push hook now runs directly from .githooks/pre-push."
echo "See .githooks/README.md for details."
Loading
Loading