From 403d8ee9d64a84ad8d7971336cfabf079b252c93 Mon Sep 17 00:00:00 2001 From: Chris0Jeky Date: Sun, 29 Mar 2026 03:41:11 +0100 Subject: [PATCH 1/5] Add check-git-env.sh for Windows git environment validation Diagnostic script that checks: - Whether git resolves to Git for Windows (not Cygwin) - Whether a stale .git/index.lock exists without active git processes Outputs actionable remediation guidance for each issue. Closes #121 --- scripts/check-git-env.sh | 90 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 scripts/check-git-env.sh diff --git a/scripts/check-git-env.sh b/scripts/check-git-env.sh new file mode 100644 index 000000000..6f9f63fd6 --- /dev/null +++ b/scripts/check-git-env.sh @@ -0,0 +1,90 @@ +#!/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 git — its path typically contains /cygdrive/ or /usr/bin/ + # and its version string includes "cygwin". + case "$GIT_PATH" in + /cygdrive/*|/usr/bin/git) + echo "[WARN] git appears to be Cygwin 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 +# --------------------------------------------------------------------------- +LOCK_FILE="$REPO_DIR/.git/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 From 9f0c749db4fb5d1fcef13bc9d41520e72edf6b0e Mon Sep 17 00:00:00 2001 From: Chris0Jeky Date: Sun, 29 Mar 2026 03:41:26 +0100 Subject: [PATCH 2/5] Update CLAUDE.md Windows Notes to reference check-git-env.sh --- CLAUDE.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 31ce1f229..fbb2738be 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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. From 1d191f2ab9b32af1027d1e5ad19bb0b735afe5fa Mon Sep 17 00:00:00 2001 From: Chris0Jeky Date: Sun, 29 Mar 2026 03:41:45 +0100 Subject: [PATCH 3/5] Update AGENTS.md Windows Git section to reference check-git-env.sh --- AGENTS.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e45a59a45..d359e29bf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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 From 8ca8896d6d672a41f6fe06df46ca402ef788ebf2 Mon Sep 17 00:00:00 2001 From: Chris0Jeky Date: Sun, 29 Mar 2026 03:42:27 +0100 Subject: [PATCH 4/5] Fix index.lock detection in git worktrees Use git rev-parse --git-dir to resolve the actual git directory instead of assuming .git is always a directory. In worktrees, .git is a file pointing elsewhere. --- scripts/check-git-env.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/check-git-env.sh b/scripts/check-git-env.sh index 6f9f63fd6..d014d1d4a 100644 --- a/scripts/check-git-env.sh +++ b/scripts/check-git-env.sh @@ -53,7 +53,10 @@ fi # --------------------------------------------------------------------------- # 2. Stale .git/index.lock detection # --------------------------------------------------------------------------- -LOCK_FILE="$REPO_DIR/.git/index.lock" +# In worktrees, .git is a file pointing to the real git dir. +# Use git rev-parse to find the actual git directory. +GIT_DIR="$(git -C "$REPO_DIR" rev-parse --git-dir 2>/dev/null || echo "$REPO_DIR/.git")" +LOCK_FILE="$GIT_DIR/index.lock" if [ -f "$LOCK_FILE" ]; then echo "" From c4e61ff503e107f401f078bf2b1a2694008d29d5 Mon Sep 17 00:00:00 2001 From: Chris0Jeky Date: Sun, 29 Mar 2026 03:55:41 +0100 Subject: [PATCH 5/5] Fix relative GIT_DIR path bug, improve Cygwin/MSYS2 comment accuracy, set +x mode - Use --absolute-git-dir instead of --git-dir to prevent lock-file check from resolving against CWD instead of REPO_DIR when invoked with an explicit path argument from a different working directory - Update detection comment to note /usr/bin/git also matches MSYS2 (non-MinGW) git, not just Cygwin - Set executable bit on the shell script (644 -> 755) --- scripts/check-git-env.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) mode change 100644 => 100755 scripts/check-git-env.sh diff --git a/scripts/check-git-env.sh b/scripts/check-git-env.sh old mode 100644 new mode 100755 index d014d1d4a..67d874e1d --- a/scripts/check-git-env.sh +++ b/scripts/check-git-env.sh @@ -27,11 +27,11 @@ else echo "[INFO] git path: $GIT_PATH" echo "[INFO] git version: $GIT_VERSION" - # Detect Cygwin git — its path typically contains /cygdrive/ or /usr/bin/ - # and its version string includes "cygwin". + # 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 git ($GIT_PATH)." + 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." @@ -55,7 +55,9 @@ fi # --------------------------------------------------------------------------- # In worktrees, .git is a file pointing to the real git dir. # Use git rev-parse to find the actual git directory. -GIT_DIR="$(git -C "$REPO_DIR" rev-parse --git-dir 2>/dev/null || echo "$REPO_DIR/.git")" +# --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