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
5 changes: 3 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ Its scope applies to the entire repo unless overridden by more specific `AGENTS.
- For product-facing slices, ensure issue scope and acceptance criteria explicitly align with the current thesis (reduce maintenance overhead/capture friction and preserve review-first trust).

### Windows Git Reliability Fallback
- If `git` resolves to Cygwin or produces signal/pipe-style failures, use `C:\Program Files\Git\cmd\git.exe` explicitly for repo operations.
- Run `bash scripts/check-git-env.sh` at the start of a session to validate git resolution and index.lock state.
- If `git` resolves to Cygwin or produces signal/pipe-style failures, use `C:\Program Files\Git\cmd\git.exe` explicitly for repo operations (or add `C:\Program Files\Git\cmd` to the front of `PATH`).
- When running automated commits in the background terminal, ALWAYS append `--no-gpg-sign` and `--no-verify` to `git commit` to prevent hidden GPG pinentry prompts from freezing the process.
- If a commit fails because `.git/index.lock` cannot be created, first check for active `git` processes; remove `.git/index.lock` only when no git process is running.
- If a commit fails because `.git/index.lock` cannot be created, first check for active `git` processes; remove `.git/index.lock` only when no git process is running. The `check-git-env.sh` script automates this detection.
- For stacked branches with small conflict surfaces, prefer `merge` over `rebase` when branch reconciliation starts stalling (for example long-running interactive/conflict loops). Resolve conflicts once, merge, and continue delivery.

### Small Mainline Exception
Expand Down
5 changes: 3 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ When launching subagents with `isolation: "worktree"`, follow the protocol in `d

## Windows Notes

- If `git` resolves to Cygwin or fails with signal errors, use `C:\Program Files\Git\cmd\git.exe` explicitly.
- Run `bash scripts/check-git-env.sh` to validate git resolution and index.lock state before a work session.
- If `git` resolves to Cygwin or fails with signal errors, use `C:\Program Files\Git\cmd\git.exe` explicitly (or add `C:\Program Files\Git\cmd` to the front of `PATH`).
- Do not chain commands with `&&` in PowerShell; use `;` and check `$LASTEXITCODE`.
- If `.git/index.lock` blocks commits, check for active git processes before removing it.
- If `.git/index.lock` blocks commits, check for active git processes before removing it. The `check-git-env.sh` script automates this check.
95 changes: 95 additions & 0 deletions scripts/check-git-env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env bash
# scripts/check-git-env.sh
# Validates the local Git environment on Windows for safe agent/local workflows.
# Checks:
# 1. git resolves to Git for Windows (not Cygwin/MSYS)
# 2. No stale .git/index.lock without an active git process
#
# Usage:
# bash scripts/check-git-env.sh # from repo root
# bash scripts/check-git-env.sh /path/to # check a specific repo

set -euo pipefail

REPO_DIR="${1:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
EXIT_CODE=0

# ---------------------------------------------------------------------------
# 1. Git executable resolution
# ---------------------------------------------------------------------------
GIT_PATH="$(command -v git 2>/dev/null || true)"

if [ -z "$GIT_PATH" ]; then
echo "[ERROR] git is not on PATH. Install Git for Windows from https://git-scm.com"
EXIT_CODE=1
else
GIT_VERSION="$(git --version 2>/dev/null || true)"
echo "[INFO] git path: $GIT_PATH"
echo "[INFO] git version: $GIT_VERSION"

# Detect Cygwin or MSYS2 (non-MinGW) git — path typically contains
# /cygdrive/ or /usr/bin/. Git for Windows (MinGW) resolves to /mingw64/bin/git.
case "$GIT_PATH" in
/cygdrive/*|/usr/bin/git)
echo "[WARN] git appears to be Cygwin or MSYS2 (non-MinGW) git ($GIT_PATH)."
echo " This can cause signal errors and path translation issues."
echo " Fix: add 'C:\\Program Files\\Git\\cmd' to the FRONT of your PATH,"
echo " or set alias git='\"C:\\Program Files\\Git\\cmd\\git.exe\"' in your shell profile."
EXIT_CODE=1
;;
esac

if echo "$GIT_VERSION" | grep -qi "cygwin"; then
echo "[WARN] git --version reports Cygwin: $GIT_VERSION"
echo " Use Git for Windows instead. See guidance above."
EXIT_CODE=1
fi

if [ $EXIT_CODE -eq 0 ]; then
echo "[OK] git resolves to a non-Cygwin executable."
fi
fi

# ---------------------------------------------------------------------------
# 2. Stale .git/index.lock detection
# ---------------------------------------------------------------------------
# In worktrees, .git is a file pointing to the real git dir.
# Use git rev-parse to find the actual git directory.
# --absolute-git-dir (Git 2.13+) returns an absolute path, avoiding the bug
# where a relative ".git" would resolve against CWD instead of REPO_DIR.
GIT_DIR="$(git -C "$REPO_DIR" rev-parse --absolute-git-dir 2>/dev/null || echo "$REPO_DIR/.git")"
LOCK_FILE="$GIT_DIR/index.lock"

if [ -f "$LOCK_FILE" ]; then
echo ""
echo "[WARN] Stale lock file found: $LOCK_FILE"

# Check for active git processes (Windows: tasklist; Unix: pgrep)
ACTIVE_GIT=""
if command -v tasklist &>/dev/null; then
ACTIVE_GIT="$(tasklist //FI "IMAGENAME eq git.exe" 2>/dev/null | grep -i "git.exe" || true)"
elif command -v pgrep &>/dev/null; then
ACTIVE_GIT="$(pgrep -a git 2>/dev/null || true)"
fi

if [ -n "$ACTIVE_GIT" ]; then
echo "[WARN] Active git process(es) detected — lock may be legitimate:"
echo "$ACTIVE_GIT"
echo " Wait for the process to finish, or kill it if stuck, then remove the lock."
else
echo "[WARN] No active git processes found. The lock file is likely stale."
echo " Safe to remove: rm \"$LOCK_FILE\""
fi
EXIT_CODE=1
else
echo "[OK] No .git/index.lock present."
fi

echo ""
if [ $EXIT_CODE -eq 0 ]; then
echo "All checks passed."
else
echo "One or more issues detected. See warnings above."
fi

exit $EXIT_CODE
Loading