Skip to content

[rustjava-merge-dropped-symbols-checker-swallows-git-failures] fix(scripts): git 실패를 삼키지 않는다 — 「못 쟀다」는 rc=2 로 말한다 - #74

Merged
Jun025 merged 2 commits into
mainfrom
feat/rustjava-merge-drops-no-silent-git-failure
Sep 18, 2026
Merged

Jun025 merged 2 commits into
mainfrom
feat/rustjava-merge-drops-no-silent-git-failure

Conversation

@Jun025

@Jun025 Jun025 commented Sep 18, 2026

Copy link
Copy Markdown
Owner

⚠ Stacked on #71 — base is feat/rustjava-merge-drop-check, not main.
scripts/check-merge-dropped-symbols.py does not exist on origin/main yet; it only exists on #71's branch, so this cannot be cut from main. Gate-3 contract 5 requires the round that merges #71 to re-parent this PR to main first, or GitHub closes it when the base branch is deleted.

The check that exists to catch a silent loss had a silent pass in it. run() returned None on a failing git and every caller wrote run(...) or "", so "git could not tell me" became "git told me nothing" — an empty diff, no parents — and the run printed ✓ (0 file(s) examined) and exited 0.

Reproduced in a real environment, not a mock. Cloning this repository at --depth 10 and running the pre-change script:

before   rc=0    ✓ 97660921 (0 file(s) examined)
                 ✓ 56bb54fa (0 file(s) examined)
after    rc=2    cannot measure: shallow clone: a merge's second parent is not here, so every
                 read of it would look empty. Fetch the full history (git fetch --unshallow)…

In a full clone those same merges examine 0 and 20 files. So a merge that reads 20 files collapsed to 0 and the whole run stayed green.

The hard part is separating "failed" from "empty". Of the 8 run() call sites, exactly one must keep tolerating a non-zero exit: git show <rev>:<path> also fails when the path is simply not in that tree, which is ordinary. rc alone cannot separate that from a missing object, so the ambiguity is removed by ruling out the environment in preflight() rather than by matching stderr text.

CI already pins fetch-depth: 0 for the merge_drops job (with a comment saying why), so raising on failure does not red existing PRs — the frequency of a shallow checkout in that job is 0. That measurement is what chose "raise" over "fetch the objects first".

Bidirectional: failure → rc=2, never ✓; a genuinely empty merge (97660921, only .md/.json changed) → still ✓ rc=0; detection unchanged (e53b2142 6, 514d5b08 6, 56bb54fa examined 20).

Predicate, filter width and PATTERNS untouched. .rs files changed: 0. Exit code 2 was already in the contract.

…ripts): git 실패를 삼키지 않는다 — 「못 쟀다」는 rc=2 로 말한다
@Jun025
Jun025 changed the base branch from feat/rustjava-merge-drop-check to main September 18, 2026 13:49
…origin/main — 승인된 원장 2파일 합집합(REPORT·STATE 상단)

게이트③ 2-c⒜ 승인 범위(원장 파일 한정) 내 해소. 양쪽 항목 전건 보존·시간순(최신 상단).
보존 증명: ours추가 REPORT 13 / STATE 8 · theirs추가 24 / 15 — 소실 0 · 외래줄 0.
해소면 밖 변경 0(scripts/check-merge-dropped-symbols.py · docs/worklog 쌍 = 핀 바이트 동일).
@Jun025
Jun025 merged commit 117c875 into main Sep 18, 2026
12 checks passed
@Jun025
Jun025 deleted the feat/rustjava-merge-drops-no-silent-git-failure branch September 18, 2026 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant