From c3167fff122a597ab6f10e6a4914441ecf0b3126 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 03:45:48 +0000 Subject: [PATCH 1/5] fix(tests): stop git_init from persisting identity into real repos Fixes #2162. Add scripts/test-git-helpers.sh with git_init_safe (refuses paths inside the current checkout) and git_test_config (per-invocation identity, no config writes). Adopt across the six listed harnesses. Co-authored-by: Kyle Sexton --- .../plugins/scripts/fleet-state.test.sh | 2 +- scripts/affected-tests.test.sh | 16 +- scripts/check-changed-skills.test.sh | 9 +- scripts/check-changelog-parity.test.sh | 140 +++++++++--------- scripts/check-docs-only.test.sh | 20 ++- scripts/test-git-helpers.sh | 40 +++++ 6 files changed, 133 insertions(+), 94 deletions(-) create mode 100644 scripts/test-git-helpers.sh diff --git a/plugins/claude-ops/skills/plugins/scripts/fleet-state.test.sh b/plugins/claude-ops/skills/plugins/scripts/fleet-state.test.sh index 593cd7f073..3eeb866925 100755 --- a/plugins/claude-ops/skills/plugins/scripts/fleet-state.test.sh +++ b/plugins/claude-ops/skills/plugins/scripts/fleet-state.test.sh @@ -341,7 +341,7 @@ CASE_NUM=$((CASE_NUM + 1)) case_dir=$(new_case_dir) project_dir="$case_dir/git-project-root" mkdir -p "$project_dir/nested/subdir" -(cd "$project_dir" && git init -q && git config user.email t@t.test && git config user.name t && git commit -q --allow-empty -m init) +(cd "$project_dir" && git init -q && git -c user.email=t@t.test -c user.name=t -c commit.gpgsign=false commit -q --allow-empty -m init) # Derive the native-Windows form from `git rev-parse --show-toplevel` itself # (forward-slash-to-backslash only) rather than `cygpath -w`: on this # machine cygpath silently 8.3-shortens a profile segment (KyleSexton -> diff --git a/scripts/affected-tests.test.sh b/scripts/affected-tests.test.sh index 9d85358691..22ee18bb9d 100755 --- a/scripts/affected-tests.test.sh +++ b/scripts/affected-tests.test.sh @@ -14,6 +14,8 @@ SELF_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SELF_DIR/.." && pwd)" SCRIPT="$SELF_DIR/affected-tests.sh" NO_SUITE="$SELF_DIR/affected-tests-no-suite.txt" +# shellcheck source=test-git-helpers.sh +. "$SELF_DIR/test-git-helpers.sh" PASS=0 FAIL=0 @@ -42,11 +44,7 @@ mk_widget_consumer() { mk_repo() { local dir dir="$(mktemp -d "${TMPDIR:-/tmp}/affected-tests-fixture.XXXXXX")" - git -C "$dir" init -q - git -C "$dir" config user.email t@t.test - git -C "$dir" config user.name test - git -C "$dir" config commit.gpgsign false - git -C "$dir" config core.autocrlf false + git_init_safe "$dir" mkdir -p "$dir/scripts" "$dir/lib" \ "$dir/plugins/alpha/hooks" "$dir/plugins/beta/hooks" @@ -80,8 +78,8 @@ mk_repo() { # A file no suite names and no no-suite pattern covers. printf 'echo orphan\n' >"$dir/scripts/zzorphan-tool.sh" - git -C "$dir" add scripts lib plugins >/dev/null - git -C "$dir" commit -qm base >/dev/null + git_test_config "$dir" add scripts lib plugins >/dev/null + git_test_config "$dir" commit -qm base >/dev/null printf '%s' "$dir" } @@ -144,8 +142,8 @@ mkdir -p "$repo/plugins/gamma/hooks" printf 'widget_helper() { echo widget; }\n' >"$repo/plugins/gamma/hooks/widget.sh" mk_widget_consumer "$repo/plugins/gamma/hooks/gamma-hook.sh" suite_body gamma-hook >"$repo/plugins/gamma/hooks/gamma-hook.test.sh" -git -C "$repo" add plugins/gamma >/dev/null -git -C "$repo" commit -qm gamma >/dev/null +git_test_config "$repo" add plugins/gamma >/dev/null +git_test_config "$repo" commit -qm gamma >/dev/null run_sel "$repo" lib/widget.sh out="$OUT" if [[ "$RC" -eq 0 ]] && has_line "$out" plugins/gamma/hooks/gamma-hook.test.sh; then diff --git a/scripts/check-changed-skills.test.sh b/scripts/check-changed-skills.test.sh index 2eb2db7b78..531afc7a77 100755 --- a/scripts/check-changed-skills.test.sh +++ b/scripts/check-changed-skills.test.sh @@ -9,6 +9,8 @@ set -uo pipefail SELF_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT="$SELF_DIR/check-changed-skills.sh" +# shellcheck source=test-git-helpers.sh +. "$SELF_DIR/test-git-helpers.sh" PASS=0 FAIL=0 @@ -35,10 +37,7 @@ chmod +x "$STUB" mk_repo() { local dir dir="$(mktemp -d)" - git -C "$dir" init -q - git -C "$dir" config user.email t@t.test - git -C "$dir" config user.name test - git -C "$dir" config commit.gpgsign false + git_init_safe "$dir" mkdir -p "$dir/scripts" cp "$SCRIPT" "$dir/scripts/check-changed-skills.sh" printf '%s' "$dir" @@ -52,7 +51,7 @@ add_skill() { printf 'content %s\n' "$RANDOM" >"$path" } -commit_all() { git -C "$1" add -A && git -C "$1" commit -qm "$2"; } +commit_all() { git_test_config "$1" add -A && git_test_config "$1" commit -qm "$2"; } base_sha() { git -C "$1" rev-parse HEAD; } # run — invoke the script from the repo root, stub as checker. diff --git a/scripts/check-changelog-parity.test.sh b/scripts/check-changelog-parity.test.sh index 5892f97142..ecfb0900f3 100755 --- a/scripts/check-changelog-parity.test.sh +++ b/scripts/check-changelog-parity.test.sh @@ -8,6 +8,8 @@ set -uo pipefail SELF_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT="$SELF_DIR/check-changelog-parity.sh" +# shellcheck source=test-git-helpers.sh +. "$SELF_DIR/test-git-helpers.sh" PASS=0 FAIL=0 @@ -30,12 +32,14 @@ mk_repo() { } git_init() { + git_init_safe "$1" +} + +git_commit() { local dir="$1" - git -C "$dir" init -q - git -C "$dir" config user.email t@t.test - git -C "$dir" config user.name test - git -C "$dir" config commit.gpgsign false - git -C "$dir" config core.autocrlf false + shift + git_test_config "$dir" add -A >/dev/null + git_test_config "$dir" commit -qm "$*" } mk_plugin() { @@ -209,11 +213,11 @@ rm -rf "$repo" repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [1.1.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump if (cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" >/dev/null 2>&1); then ok "bump + '## [x.y.z]' entry passes --check-bump"; else fail "bump+entry wrongly failed"; fi rm -rf "$repo" @@ -223,11 +227,11 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 0.51.8 yes printf '# Changelog\n\n## [0.51.8]\n\n### Fixed\n\n- predecessor note\n\n## [0.51.7]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "0.51.9" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [0.51.9]\n\n### Fixed\n\n- new note\n- predecessor note\n\n## [0.51.7]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"ABSORBED CHANGELOG HEADING"*"alpha"* && "$out" == *"## [0.51.8]"* ]]; then ok "absorbed predecessor release heading fails --check-bump"; else fail "absorbed heading not caught: rc=$rc out='$out'"; fi @@ -251,7 +255,7 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" { @@ -261,7 +265,7 @@ printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude done printf '\n## [1.0.0]\n' } >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump if command -v gawk >/dev/null 2>&1; then mkdir -p "$repo/bin" printf '#!/bin/sh\nexec gawk "$@"\n' >"$repo/bin/awk" @@ -279,11 +283,11 @@ rm -rf "$repo" repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## 1.1.0 — 2026-07-20\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"CHANGELOG FORMAT"*"alpha"* && "$out" == *"## 1.1.0"* && "$out" != *"UNDOCUMENTED BUMP"* ]]; then ok "bump + unbracketed heading -> FORMAT error (not UNDOCUMENTED)"; else fail "format-split not caught: rc=$rc out='$out'"; fi @@ -296,11 +300,11 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [1.1.0]\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump if (cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" >/dev/null 2>&1); then ok "bump adding a NEW '## [x.y.z]' entry (absent at base) passes --check-bump"; else fail "newly-added entry wrongly failed"; fi rm -rf "$repo" @@ -312,10 +316,10 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.1.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"PRE-EXISTING CHANGELOG ENTRY"*"alpha"* && "$out" != *"UNDOCUMENTED BUMP"* ]]; then ok "bump reusing a base-pre-existing '## [x.y.z]' entry fails --check-bump"; else fail "preexisting-entry not caught: rc=$rc out='$out'"; fi @@ -328,11 +332,11 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.0.1+build.1" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [1.0.1+build.1]\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump if (cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" >/dev/null 2>&1); then ok "SemVer build-metadata version with a proper entry passes (no regex leak)"; else fail "build-metadata version wrongly failed"; fi rm -rf "$repo" @@ -345,11 +349,11 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [1.0.0]\n\nNext release will be titled "## [1.1.0]" per convention.\n ## [1.1.0] (example, indented, not a heading)\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"UNDOCUMENTED BUMP"*"alpha"* && "$out" != *"PRE-EXISTING"* ]]; then ok "version string in prose/indented example does not satisfy the anchored heading match"; else fail "unanchored-mention not caught: rc=$rc out='$out'"; fi @@ -362,12 +366,12 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" # shellcheck disable=SC2016 # single quotes are deliberate: the backtick fence and \n are literal changelog bytes, not shell expansions printf '# Changelog\n\nExample of a heading:\n\n```\n## [1.1.0]\n```\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"UNDOCUMENTED BUMP"*"alpha"* && "$out" != *"PRE-EXISTING"* ]]; then ok "fenced-code example heading (column zero inside a fence) does not satisfy --check-bump"; else fail "fenced-block heading wrongly satisfied gate: rc=$rc out='$out'"; fi @@ -381,12 +385,12 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" # shellcheck disable=SC2016 # single quotes are deliberate: the backtick/tilde fences and \n are literal changelog bytes printf '# Changelog\n\n```\n~~~\n## [1.1.0]\n```\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"UNDOCUMENTED BUMP"*"alpha"* && "$out" != *"PRE-EXISTING"* ]]; then ok "mismatched inner fence delimiter (tilde line inside a backtick fence) does not prematurely close"; else fail "fence delimiter mismatch wrongly toggled: rc=$rc out='$out'"; fi @@ -401,12 +405,12 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" # shellcheck disable=SC2016 # single quotes are deliberate: fence lines are literal changelog bytes printf '# Changelog\n\n```\n```not-a-close\n ```\n## [1.1.0]\n```\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"UNDOCUMENTED BUMP"*"alpha"* && "$out" != *"PRE-EXISTING"* ]]; then ok "non-closing fence lines (text suffix, four-space indent) do not close a fence"; else fail "non-closing fence line wrongly closed the fence: rc=$rc out='$out'"; fi @@ -418,11 +422,11 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"UNDOCUMENTED BUMP"*"alpha"* && "$out" != *"PRE-EXISTING"* ]]; then ok "heading inside an HTML comment does not satisfy --check-bump"; else fail "HTML-comment heading wrongly satisfied gate: rc=$rc out='$out'"; fi @@ -435,11 +439,11 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog (typo fix)\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"UNDOCUMENTED BUMP"*"alpha"* ]]; then ok "bump + unrelated changelog edit (no new-version entry) fails --check-bump"; else fail "unrelated-edit bump not caught: rc=$rc out='$out'"; fi @@ -449,10 +453,10 @@ rm -rf "$repo" repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"UNDOCUMENTED BUMP"*"alpha"* ]]; then ok "bump without changelog fails --check-bump (synthetic undocumented bump caught)"; else fail "undocumented bump not caught: rc=$rc out='$out'"; fi @@ -462,10 +466,10 @@ rm -rf "$repo" repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf 'unrelated\n' >"$repo/plugins/alpha/README.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm noop +git_commit "$repo" noop if (cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" >/dev/null 2>&1); then ok "unchanged version passes --check-bump"; else fail "unchanged version wrongly failed"; fi rm -rf "$repo" @@ -473,10 +477,10 @@ rm -rf "$repo" repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" mk_plugin "$repo" beta 1.0.0 no -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm add-beta +git_commit "$repo" add-beta if (cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" >/dev/null 2>&1); then ok "new plugin skipped by --check-bump"; else fail "new plugin wrongly failed --check-bump"; fi rm -rf "$repo" @@ -493,17 +497,17 @@ mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" mk_plugin "$repo" beta 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/beta/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base fork="$(git -C "$repo" rev-parse HEAD)" # main advances alpha (a plugin the PR never touches) printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [1.1.0]\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'main bumps alpha' +git_commit "$repo" 'main bumps alpha' main="$(git -C "$repo" rev-parse HEAD)" # PR branch forks from base and edits only beta's changelog (alpha left stale) git -C "$repo" checkout -q -b pr "$fork" printf '# Changelog\n\ntypo fix\n\n## [1.0.0]\n' >"$repo/plugins/beta/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'pr edits beta only' +git_commit "$repo" 'pr edits beta only' out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$main" 2>&1)" rc=$? if [[ $rc -eq 0 ]]; then ok "untouched plugin advanced only on the base ref is not flagged (branch staleness scoped out)"; else fail "branch-staleness wrongly flagged: rc=$rc out='$out'"; fi @@ -517,15 +521,15 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base fork="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [1.1.0]\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'main bumps alpha' +git_commit "$repo" 'main bumps alpha' main="$(git -C "$repo" rev-parse HEAD)" git -C "$repo" checkout -q -b pr "$fork" printf 'docs\n' >"$repo/plugins/alpha/README.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'pr edits alpha README only' +git_commit "$repo" 'pr edits alpha README only' out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$main" 2>&1)" rc=$? if [[ $rc -eq 0 ]]; then ok "cosmetic touch under a plugin dir does not pull a main-only advance into scope (manifest-scoped)"; else fail "manifest-scoping regressed to plugin-root: rc=$rc out='$out'"; fi @@ -541,15 +545,15 @@ mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" mk_plugin "$repo" beta 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/beta/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base fork="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [1.1.0]\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'main bumps alpha' +git_commit "$repo" 'main bumps alpha' main="$(git -C "$repo" rev-parse HEAD)" git -C "$repo" checkout -q -b pr "$fork" printf '{ "name": "beta", "version": "2.0.0" }\n' >"$repo/plugins/beta/.claude-plugin/plugin.json" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'pr bumps beta, no entry' +git_commit "$repo" 'pr bumps beta, no entry' out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$main" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"UNDOCUMENTED BUMP"*"beta"* && "$out" != *"alpha"* ]]; then ok "a plugin the branch bumped is still checked while the main-only advance is scoped out"; else fail "diff-scoping incorrectly scoped: rc=$rc out='$out'"; fi @@ -565,16 +569,16 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 0.21.9 yes printf '# Changelog\n\n## [0.21.9]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base fork="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "0.25.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [0.25.0]\n\n## [0.21.9]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'main advances alpha to 0.25.0' +git_commit "$repo" 'main advances alpha to 0.25.0' main="$(git -C "$repo" rev-parse HEAD)" git -C "$repo" checkout -q -b pr "$fork" printf '{ "name": "alpha", "version": "0.21.10" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [0.21.10]\n\n## [0.21.9]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'pr bumps alpha to 0.21.10 off a stale base' +git_commit "$repo" 'pr bumps alpha to 0.21.10 off a stale base' out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$main" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"VERSION REGRESSION"*"alpha"* && "$out" != *"UNDOCUMENTED"* && "$out" != *"PRE-EXISTING"* ]]; then ok "bump below the base ref's current version fails as VERSION REGRESSION despite valid parity"; else fail "version regression not caught: rc=$rc out='$out'"; fi @@ -588,16 +592,16 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base fork="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [1.1.0]\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'main merges its own 1.1.0' +git_commit "$repo" 'main merges its own 1.1.0' main="$(git -C "$repo" rev-parse HEAD)" git -C "$repo" checkout -q -b pr "$fork" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [1.1.0]\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'pr also bumps to 1.1.0' +git_commit "$repo" 'pr also bumps to 1.1.0' out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$main" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"VERSION COLLISION"*"alpha"* && "$out" != *"UNDOCUMENTED"* ]]; then ok "bump equal to the base ref's current version fails as VERSION COLLISION (not skipped as not-bumped)"; else fail "version collision not caught: rc=$rc out='$out'"; fi @@ -614,7 +618,7 @@ printf '# Changelog ## [1.0.0] ' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base fork="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" } ' >"$repo/plugins/alpha/.claude-plugin/plugin.json" @@ -624,7 +628,7 @@ printf '# Changelog ## [1.0.0] ' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'main merges its own 1.1.0' +git_commit "$repo" 'main merges its own 1.1.0' main="$(git -C "$repo" rev-parse HEAD)" git -C "$repo" checkout -q -b pr "$fork" printf '{ "name": "alpha", "version": "1.1.0" } @@ -635,7 +639,7 @@ printf '# Changelog ## [1.0.0] ' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'pr also bumps to 1.1.0' +git_commit "$repo" 'pr also bumps to 1.1.0' git -C "$repo" checkout -q "$main" git -C "$repo" checkout -q -b synthetic git -C "$repo" merge -q --no-ff -m 'synthetic PR merge' pr >/dev/null 2>&1 @@ -653,7 +657,7 @@ printf '# Changelog ## [1.0.0] ' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base main="$(git -C "$repo" rev-parse HEAD)" git -C "$repo" checkout -q -b pr printf '{ "name": "alpha", "version": "1.two.0" } @@ -664,7 +668,7 @@ printf '# Changelog ## [1.0.0] ' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'pr ships a malformed version' +git_commit "$repo" 'pr ships a malformed version' out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$main" 2>&1)" rc=$? if [[ $rc -ne 0 && "$out" == *"non-SemVer"*"1.two.0"* ]]; then ok "malformed manifest version refuses loudly before the sort key"; else fail "malformed version not refused: rc=$rc out='$out'"; fi @@ -678,16 +682,16 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base fork="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [1.1.0]\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'main bumps alpha to 1.1.0' +git_commit "$repo" 'main bumps alpha to 1.1.0' main="$(git -C "$repo" rev-parse HEAD)" git -C "$repo" checkout -q -b pr "$fork" printf '{ "name": "alpha", "version": "1.2.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [1.2.0]\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'pr bumps past the advance to 1.2.0' +git_commit "$repo" 'pr bumps past the advance to 1.2.0' out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$main" 2>&1)" rc=$? if [[ $rc -eq 0 ]]; then ok "bump strictly above the base ref's advanced version passes --check-bump"; else fail "forward bump past an advanced base wrongly failed: rc=$rc out='$out'"; fi @@ -700,11 +704,11 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 0.9.0 yes printf '# Changelog\n\n## [0.9.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "0.10.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [0.10.0]\n\n## [0.9.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm bump +git_commit "$repo" bump out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" 2>&1)" rc=$? if [[ $rc -eq 0 ]]; then ok "0.9.0 -> 0.10.0 passes (monotonicity is numeric, not lexical)"; else fail "cross-segment bump wrongly failed: rc=$rc out='$out'"; fi @@ -718,15 +722,15 @@ repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes printf '# Changelog\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base fork="$(git -C "$repo" rev-parse HEAD)" printf '{ "name": "alpha", "version": "1.1.0" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" printf '# Changelog\n\n## [1.1.0]\n\n## [1.0.0]\n' >"$repo/plugins/alpha/CHANGELOG.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'main bumps alpha' +git_commit "$repo" 'main bumps alpha' main="$(git -C "$repo" rev-parse HEAD)" git -C "$repo" checkout -q -b pr "$fork" printf '{ "name": "alpha", "version": "1.0.0", "description": "d" }\n' >"$repo/plugins/alpha/.claude-plugin/plugin.json" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'pr edits alpha manifest, no version change' +git_commit "$repo" 'pr edits alpha manifest, no version change' out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$main" 2>&1)" rc=$? if [[ $rc -eq 0 ]]; then ok "manifest edit without a version change on a stale branch is not flagged (fork-scoped, no regression false positive)"; else fail "cosmetic manifest edit wrongly flagged: rc=$rc out='$out'"; fi @@ -742,13 +746,13 @@ rm -rf "$repo" repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base base="$(git -C "$repo" rev-parse HEAD)" # Orphan branch: a second root commit with no ancestor in common with base. git -C "$repo" checkout -q --orphan orphan git -C "$repo" rm -rq --cached . >/dev/null 2>&1 || true mk_plugin "$repo" alpha 1.1.0 yes -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm 'orphan root' +git_commit "$repo" 'orphan root' out="$(cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump "$base" 2>&1)" rc=$? if [[ $rc -eq 2 && "$out" == *"failed"* ]]; then ok "no common ancestor -> git diff fails -> gate fails loud (exit 2), never silent pass"; else fail "no-common-ancestor did not fail loud: rc=$rc out='$out'"; fi @@ -758,7 +762,7 @@ rm -rf "$repo" repo="$(mk_repo)" git_init "$repo" mk_plugin "$repo" alpha 1.0.0 yes -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm base +git_commit "$repo" base (cd "$repo" && bash scripts/check-changelog-parity.sh --check-bump does-not-exist >/dev/null 2>&1) if [[ $? -eq 2 ]]; then ok "unresolvable base ref -> exit 2"; else fail "bad base ref did not exit 2"; fi rm -rf "$repo" diff --git a/scripts/check-docs-only.test.sh b/scripts/check-docs-only.test.sh index f2cc70fab0..f74675df83 100755 --- a/scripts/check-docs-only.test.sh +++ b/scripts/check-docs-only.test.sh @@ -10,6 +10,8 @@ set -uo pipefail SELF_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT="$SELF_DIR/check-docs-only.sh" ALLOWLIST="$SELF_DIR/docs-only-paths.txt" +# shellcheck source=test-git-helpers.sh +. "$SELF_DIR/test-git-helpers.sh" PASS=0 FAIL=0 @@ -25,11 +27,7 @@ ok() { mk_repo() { local dir dir="$(mktemp -d)" - git -C "$dir" init -q - git -C "$dir" config user.email t@t.test - git -C "$dir" config user.name test - git -C "$dir" config commit.gpgsign false - git -C "$dir" config core.autocrlf false + git_init_safe "$dir" mkdir -p "$dir/scripts" cp "$SCRIPT" "$dir/scripts/check-docs-only.sh" cp "$ALLOWLIST" "$dir/scripts/docs-only-paths.txt" @@ -45,8 +43,8 @@ mk_repo() { printf 'seed\n' >"$dir/plugins/miro/index.ts" printf 'seed\n' >"$dir/.github/workflows/ci.yml" printf 'seed\n' >"$dir/package-lock.json" - git -C "$dir" add -A >/dev/null - git -C "$dir" commit -qm base + git_test_config "$dir" add -A >/dev/null + git_test_config "$dir" commit -qm base printf '%s' "$dir" } @@ -63,8 +61,8 @@ assert_flag() { mkdir -p "$repo/$(dirname "$p")" printf 'changed %s\n' "$RANDOM" >"$repo/$p" done - git -C "$repo" add -A >/dev/null - git -C "$repo" commit -qm change >/dev/null + git_test_config "$repo" add -A >/dev/null + git_test_config "$repo" commit -qm change >/dev/null out="$(cd "$repo" && bash scripts/check-docs-only.sh "$base" 2>/dev/null)" if [[ "$out" == "docs_only=$expected" ]]; then ok "$label -> $expected" @@ -118,7 +116,7 @@ repo="$(mk_repo)" base="$(git -C "$repo" rev-parse HEAD)" : >"$repo/empty-allowlist.txt" printf 'changed\n' >"$repo/docs/topics/example/PLAN.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm change >/dev/null +git_test_config "$repo" add -A >/dev/null && git_test_config "$repo" commit -qm change >/dev/null out="$(cd "$repo" && DOCS_ONLY_ALLOWLIST=empty-allowlist.txt bash scripts/check-docs-only.sh "$base" 2>/dev/null)" if [[ "$out" == "docs_only=false" ]]; then ok "empty allowlist -> false (fail-closed)" @@ -131,7 +129,7 @@ rm -rf "$repo" repo="$(mk_repo)" base="$(git -C "$repo" rev-parse HEAD)" printf 'changed\n' >"$repo/docs/topics/example/PLAN.md" -git -C "$repo" add -A >/dev/null && git -C "$repo" commit -qm change >/dev/null +git_test_config "$repo" add -A >/dev/null && git_test_config "$repo" commit -qm change >/dev/null gho="$(mktemp)" (cd "$repo" && GITHUB_OUTPUT="$gho" bash scripts/check-docs-only.sh "$base" >/dev/null 2>&1) if grep -qx 'docs_only=true' "$gho"; then diff --git a/scripts/test-git-helpers.sh b/scripts/test-git-helpers.sh new file mode 100644 index 0000000000..71fce300f1 --- /dev/null +++ b/scripts/test-git-helpers.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# Shared helpers for test harnesses that build throwaway git repositories. +# Sourced by repo-level *.test.sh files — not executed directly. +# +# git_test_config wraps git -C with throwaway identity and signing settings so +# nothing is persisted into a repository's .git/config. git_init_safe refuses +# to initialize inside the current checkout tree. + +git_test_config() { + local dir="$1" + shift + git -C "$dir" \ + -c user.email=t@t.test \ + -c user.name=test \ + -c commit.gpgsign=false \ + -c core.autocrlf=false \ + "$@" +} + +git_init_safe() { + local dir="$1" + if [[ -z "$dir" || ! -d "$dir" ]]; then + echo "git_init_safe: missing or non-directory path: ${dir:-}" >&2 + return 1 + fi + local abs_dir repo_root + abs_dir="$(cd "$dir" && pwd)" + repo_root="$(git rev-parse --show-toplevel 2>/dev/null)" || true + if [[ -n "$repo_root" ]]; then + local abs_repo + abs_repo="$(cd "$repo_root" && pwd)" + case "$abs_dir" in + "$abs_repo" | "$abs_repo"/*) + echo "git_init_safe: refusing path inside current repository: $abs_dir" >&2 + return 1 + ;; + esac + fi + git_test_config "$dir" init -q +} From 34599288538b8db0e11f64d65407e251bf64cb55 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 04:38:03 +0000 Subject: [PATCH 2/5] chore: retrigger CI after pr-issue-linkage body fix Co-authored-by: Kyle Sexton From c3ac8f838f5310fff440d4b3e1a3f9ac27e5e6f7 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 04:40:26 +0000 Subject: [PATCH 3/5] fix(tests): configure throwaway repo identity for merge commits in parity tests Co-authored-by: Kyle Sexton --- scripts/check-changelog-parity.test.sh | 2 +- scripts/test-git-helpers.sh | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/check-changelog-parity.test.sh b/scripts/check-changelog-parity.test.sh index ecfb0900f3..7761285d7a 100755 --- a/scripts/check-changelog-parity.test.sh +++ b/scripts/check-changelog-parity.test.sh @@ -32,7 +32,7 @@ mk_repo() { } git_init() { - git_init_safe "$1" + git_init_test_repo "$1" } git_commit() { diff --git a/scripts/test-git-helpers.sh b/scripts/test-git-helpers.sh index 71fce300f1..d4102b54ba 100644 --- a/scripts/test-git-helpers.sh +++ b/scripts/test-git-helpers.sh @@ -38,3 +38,14 @@ git_init_safe() { fi git_test_config "$dir" init -q } + +# Initialize a throwaway repo outside the checkout and give it a local identity. +# Local config on a temp dir cannot leak into the real repository tree. +git_init_test_repo() { + local dir="$1" + git_init_safe "$dir" || return 1 + git_test_config "$dir" config user.email t@t.test + git_test_config "$dir" config user.name test + git_test_config "$dir" config commit.gpgsign false + git_test_config "$dir" config core.autocrlf false +} From 7e7175bbbf12662dd8f35b2f168819ec3a9ee620 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 04:45:17 +0000 Subject: [PATCH 4/5] fix(tests): mark test-git-helpers.sh executable in git index Co-authored-by: Kyle Sexton --- scripts/test-git-helpers.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/test-git-helpers.sh diff --git a/scripts/test-git-helpers.sh b/scripts/test-git-helpers.sh old mode 100644 new mode 100755 From 813a41e13eb863ac64c06657842f2226a6d0b230 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 04:54:27 +0000 Subject: [PATCH 5/5] fix(tests): satisfy shellcheck SC2249 default case in git_init_safe Co-authored-by: Kyle Sexton --- scripts/test-git-helpers.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/test-git-helpers.sh b/scripts/test-git-helpers.sh index d4102b54ba..2e29ff9562 100755 --- a/scripts/test-git-helpers.sh +++ b/scripts/test-git-helpers.sh @@ -34,6 +34,8 @@ git_init_safe() { echo "git_init_safe: refusing path inside current repository: $abs_dir" >&2 return 1 ;; + *) + ;; esac fi git_test_config "$dir" init -q