From 6728653f92457f0f9fc039ec03b1a0086e309c87 Mon Sep 17 00:00:00 2001 From: Cuarroc <47299143+Cuarroc@users.noreply.github.com> Date: Fri, 9 Oct 2026 04:55:23 +0200 Subject: [PATCH] fix(review): resolve PR heads without shared FETCH_HEAD Concurrent run-local.sh runs in one checkout overwrote FETCH_HEAD, so each prompt could review the wrong PR. Fetch into refs/pa-review/pr- and record Head: in the prompt. Test-First: scripts/test-review-local.sh::parallel PR fetches keep distinct diffs (no shared FETCH_HEAD) Co-authored-by: Cursor --- scripts/review/run-local.sh | 17 ++++++++---- scripts/test-review-local.sh | 54 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/scripts/review/run-local.sh b/scripts/review/run-local.sh index 8052b7ad..0a3737af 100755 --- a/scripts/review/run-local.sh +++ b/scripts/review/run-local.sh @@ -252,14 +252,19 @@ git -C "$TOP" rev-parse --verify --quiet "$base^{commit}" > /dev/null \ || die 2 "Basis $base nicht gefunden (git fetch origin main?)." if [ -n "$pr" ]; then - git -C "$TOP" fetch --quiet origin "pull/$pr/head" 2> /dev/null \ - || die 2 "PR $pr nicht gefunden: 'git fetch origin pull/$pr/head' schlug fehl (Nummer falsch, origin nicht erreichbar oder kein Zugriff)." - head_ref="$(git -C "$TOP" rev-parse FETCH_HEAD)" || die 2 "PR $pr: FETCH_HEAD nicht lesbar." - [ -n "$head_ref" ] || die 2 "PR $pr: FETCH_HEAD ist leer." + # Private ref per PR: concurrent runs in one checkout must not share FETCH_HEAD + # (a second fetch overwrites it before rev-parse). Force-update keeps the ref + # current when the same PR is reviewed again. + pr_ref="refs/pa-review/pr-$pr" + git -C "$TOP" fetch --quiet origin "+pull/$pr/head:$pr_ref" 2> /dev/null \ + || die 2 "PR $pr nicht gefunden: 'git fetch origin +pull/$pr/head:$pr_ref' schlug fehl (Nummer falsch, origin nicht erreichbar oder kein Zugriff)." + head_ref="$(git -C "$TOP" rev-parse --verify "$pr_ref^{commit}")" \ + || die 2 "PR $pr: Ref $pr_ref nicht lesbar." + [ -n "$head_ref" ] || die 2 "PR $pr: Ref $pr_ref ist leer." [ -n "$label" ] || label="pr$pr" subject="PR #$pr" else - head_ref="HEAD" + head_ref="$(git -C "$TOP" rev-parse --verify HEAD)" || die 2 "HEAD nicht lesbar." branch="$(git -C "$TOP" rev-parse --abbrev-ref HEAD 2> /dev/null)" if [ -z "$branch" ] || [ "$branch" = HEAD ]; then branch="head-$(git -C "$TOP" rev-parse --short HEAD)" @@ -299,6 +304,8 @@ prompt_file="$out_dir/review_prompt_$label.md" cat << EOF # Review request $label: $subject against $base +Head: $head_ref + You are an independent reviewer (not the author${author:+; the author is a $author model}). Review the change below for correctness bugs, gaps, and safety regressions. Be concrete: cite file and line, say what breaks and when. Rate each finding diff --git a/scripts/test-review-local.sh b/scripts/test-review-local.sh index 1ac243df..a93c3285 100755 --- a/scripts/test-review-local.sh +++ b/scripts/test-review-local.sh @@ -450,6 +450,60 @@ else bad "kilo-Protokollname kollidiert: rc=$rc"; echo "$out"; ls "$tmp/k8" 2>&1 fi +# 14. Parallel PR fetches must not share FETCH_HEAD. A git wrapper overwrites +# FETCH_HEAD after a bare `pull/N/head` fetch (the old pattern); a private +# destination ref must keep each prompt on its own PR head. +( + cd "$REPO" || exit 1 + git checkout -q -b pr8-branch main + echo "MARKER_PR8_ONLY" > pr8.txt + git add pr8.txt && git commit -q -m pr8 + git push -q origin HEAD:refs/pull/8/head + git checkout -q claude/demo-branch +) +sha7="$(git -C "$REPO" ls-remote origin refs/pull/7/head | awk '{print $1}')" +sha8="$(git -C "$REPO" ls-remote origin refs/pull/8/head | awk '{print $1}')" +REAL_GIT="$(command -v git)" +mkdir -p "$tmp/bin-race" +cat > "$tmp/bin-race/git" </dev/null \ + && ! grep -q "MARKER_PR8_ONLY" "$tmp/race7/review_prompt_pr7.md" 2>/dev/null \ + && grep -q "MARKER_PR8_ONLY" "$tmp/race8/review_prompt_pr8.md" 2>/dev/null \ + && ! grep -q "MARKER_LINE" "$tmp/race8/review_prompt_pr8.md" 2>/dev/null \ + && grep -q "^Head: $sha7\$" "$tmp/race7/review_prompt_pr7.md" 2>/dev/null \ + && grep -q "^Head: $sha8\$" "$tmp/race8/review_prompt_pr8.md" 2>/dev/null; then + ok "parallel PR fetches keep distinct diffs (no shared FETCH_HEAD)" +else + bad "parallel PR FETCH_HEAD race: rc7=$rc7 rc8=$rc8"; echo "$out7"; echo "$out8" + ls "$tmp/race7" "$tmp/race8" 2>&1 + head -n 8 "$tmp/race7/review_prompt_pr7.md" 2>&1 + head -n 8 "$tmp/race8/review_prompt_pr8.md" 2>&1 +fi + echo if [ "$fails" -eq 0 ]; then echo "test-review-local: alles gruen."