#!/usr/bin/env bash # Case 01: 'git status' inside an .hg repository must be blocked. set -u tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT mkdir -p "$tmp/repo/.hg" mkdir -p "$tmp/repo/sub" input=$(jq -n --arg cwd "$tmp/repo/sub" --arg cmd "git status" '{ cwd: $cwd, hook_event_name: "PreToolUse", tool_name: "Bash", tool_input: { command: $cmd } }') # Run hook; capture stderr and exit code. err=$(echo "$input" | "$HOOK_SCRIPT" 2>&1 >/dev/null) rc=$? if [[ $rc -ne 2 ]]; then echo "expected exit 2 (blocked), got $rc" echo "stderr was: $err" exit 1 fi if ! grep -q "hg status" <<<"$err"; then echo "expected stderr to suggest 'hg status', got: $err" exit 1 fi #!/usr/bin/env bash # Case 02: 'git --version' outside any .hg/.git context must be allowed. set -u tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT input=$(jq -n --arg cwd "$tmp" --arg cmd "git --version" '{ cwd: $cwd, hook_event_name: "PreToolUse", tool_name: "Bash", tool_input: { command: $cmd } }') if ! echo "$input" | "$HOOK_SCRIPT" >/dev/null 2>&1; then echo "expected exit 0 (allow), got non-zero" exit 1 fi #!/usr/bin/env bash # Case 03: closer .git wins over outer .hg, AND bare git repos # (HEAD/refs/objects in cwd, no .git subdir) inside an .hg ancestor allow. set -u tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT # Sub-case A: regular .git nested under .hg mkdir -p "$tmp/outer/.hg" mkdir -p "$tmp/outer/inner/.git" input=$(jq -n --arg cwd "$tmp/outer/inner" --arg cmd "git log" '{ cwd: $cwd, hook_event_name: "PreToolUse", tool_name: "Bash", tool_input: { command: $cmd } }') if ! echo "$input" | "$HOOK_SCRIPT" >/dev/null 2>&1; then echo "sub-case A (nested .git) expected exit 0, got non-zero" exit 1 fi # Sub-case B: bare git repo (no .git subdir) inside .hg ancestor mkdir -p "$tmp/outer/testdata/repo.git/refs" mkdir -p "$tmp/outer/testdata/repo.git/objects" touch "$tmp/outer/testdata/repo.git/HEAD" input=$(jq -n --arg cwd "$tmp/outer/testdata/repo.git" --arg cmd "git log" '{ cwd: $cwd, hook_event_name: "PreToolUse", tool_name: "Bash", tool_input: { command: $cmd } }') if ! echo "$input" | "$HOOK_SCRIPT" >/dev/null 2>&1; then echo "sub-case B (bare repo) expected exit 0, got non-zero" exit 1 fi #!/usr/bin/env bash # Case 04: 'hg status' inside an .hg repo must be allowed (only git is blocked). set -u tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT mkdir -p "$tmp/repo/.hg" input=$(jq -n --arg cwd "$tmp/repo" --arg cmd "hg status" '{ cwd: $cwd, hook_event_name: "PreToolUse", tool_name: "Bash", tool_input: { command: $cmd } }') if ! echo "$input" | "$HOOK_SCRIPT" >/dev/null 2>&1; then echo "expected exit 0 (allow), got non-zero" exit 1 fi #!/usr/bin/env bash # Case 05: 'FOO=bar git status' inside an .hg repo must be blocked # (env-var prefix correctly skipped to find the real leading command). set -u tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT mkdir -p "$tmp/repo/.hg" input=$(jq -n --arg cwd "$tmp/repo" --arg cmd "FOO=bar GIT_PAGER=cat git status" '{ cwd: $cwd, hook_event_name: "PreToolUse", tool_name: "Bash", tool_input: { command: $cmd } }') err=$(echo "$input" | "$HOOK_SCRIPT" 2>&1 >/dev/null) rc=$? if [[ $rc -ne 2 ]]; then echo "expected exit 2 (blocked), got $rc" echo "stderr: $err" exit 1 fi #!/usr/bin/env bash # Case 06: 'ls -la' inside an .hg repo must be allowed (not a git command). set -u tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT mkdir -p "$tmp/repo/.hg" input=$(jq -n --arg cwd "$tmp/repo" --arg cmd "ls -la" '{ cwd: $cwd, hook_event_name: "PreToolUse", tool_name: "Bash", tool_input: { command: $cmd } }') if ! echo "$input" | "$HOOK_SCRIPT" >/dev/null 2>&1; then echo "expected exit 0 (allow), got non-zero" exit 1 fi #!/usr/bin/env bash # Case 07: 'cd /tmp && git init' inside an .hg repo must be allowed # (only the leading token is inspected — this is the documented escape valve). set -u tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT mkdir -p "$tmp/repo/.hg" input=$(jq -n --arg cwd "$tmp/repo" --arg cmd "cd /tmp && git init" '{ cwd: $cwd, hook_event_name: "PreToolUse", tool_name: "Bash", tool_input: { command: $cmd } }') if ! echo "$input" | "$HOOK_SCRIPT" >/dev/null 2>&1; then echo "expected exit 0 (allow), got non-zero" exit 1 fi