Skip to main content

github-merge-502-already-merged

`gh pr merge` 가 502/504 를 내도 머지는 이미 됐을 수 있다 — GitHub 는 머지를 수행한 뒤 PR 레코드 갱신에서 죽는다. 그러면 스쿼시 커밋은 main 에 있는데 PR 은 `state=open, merged=false` 로 남고, 브랜치도 안 지워진다. 재시도하기 전에 `git log origin/main` 을 먼저 봐라. 트리거: gh pr merge 502/Bad Gateway, "머지 실패"인데 CI 는 green, mergeStateStatus 가 갑자기 BEHIND, PR 이 열려 있는데 커밋이 main 에 있음.

الانتقال إلى التثبيت

معلومات المصدر

المستودع
blas1n/claude-skills
آخر نشاط في المصدر
١٢ أغسطس ٢٠٢٦ في ٠٣:٤٥
لغة SKILL.md المكتشفة
الكورية
النجوم
٢
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
github-merge-502-already-merged
description
`gh pr merge` 가 502/504 를 내도 머지는 이미 됐을 수 있다 — GitHub 는 머지를 수행한 뒤 PR 레코드 갱신에서 죽는다. 그러면 스쿼시 커밋은 main 에 있는데 PR 은 `state=open, merged=false` 로 남고, 브랜치도 안 지워진다. 재시도하기 전에 `git log origin/main` 을 먼저 봐라. 트리거: gh pr merge 502/Bad Gateway, "머지 실패"인데 CI 는 green, mergeStateStatus 가 갑자기 BEHIND, PR 이 열려 있는데 커밋이 main 에 있음.
# `gh pr merge` 의 502 는 "머지 안 됐다"가 아니다 ## Problem ``` $ gh pr merge 736 --squash --delete-branch non-200 OK status code: 502 Bad Gateway ... <center>nginx</center> ``` 반사적으로 재시도하거나 "머지 실패"로 보고하게 된다. **둘 다 틀릴 수 있다.** - **증상**: 머지 명령이 502. 이어서 `gh pr view` 를 보면 `state: OPEN`, `mergedAt: null`, `mergeStateStatus: BEHIND` — 전부 "안 됐다"로 읽힌다. 리모트 브랜치도 그대로 있다. - **실제**: `git fetch && git log origin/main` 을 보면 **스쿼시 커밋이 이미 올라가 있다.** - **근본 원인**: 머지는 두 단계다 — ①ref 를 전진시킨다 ②PR 레코드를 merged 로 표시하고 브랜치를 지운다. 502 는 ① 이후 ② 에서 났고, GitHub 은 그것을 **되감지 않는다.** 스쿼시 머지는 커밋 SHA 가 브랜치 tip 과 달라서 GitHub 의 자동 감지도 안 걸린다. - **왜 위험한가**: 재시도하면 이미 반영된 변경을 다시 머지하려 들고(빈 머지 또는 충돌), "머지 실패"로 보고하면 **이미 배포 파이프라인이 물어간 변경**을 없는 것으로 취급하게 된다. ## Solution 502/504 를 받으면 **재시도 금지, 먼저 사실을 확인**한다: ```bash git fetch -q origin git log --oneline -3 origin/main # 내 PR 번호의 스쿼시 커밋이 있는가? # 있다면 — 내용까지 동일성 확인 (부분 반영이 아님을 증명) git diff --stat origin/main <my-branch> # 비어 있어야 한다 # 동일하면 머지는 끝난 것이다. PR 레코드만 손으로 정리한다 gh pr close <N> --comment "머지 API 502; 스쿼시 커밋은 main 에 반영됨(<sha>). 레코드만 수동 정리." git push origin --delete <my-branch> ``` ⚠️ `gh pr close --delete-branch` 는 다른 워크트리가 그 브랜치를 쓰고 있으면 `fatal: 'main' is already used by worktree at ...` 로 로컬 삭제에서 죽는다. 리모트 삭제는 `git push origin --delete` 로 따로 한다. 배포 확인도 잊지 마라 — 머지가 됐으므로 **autodeploy 폴러는 이미 물어간다**: ```bash curl -s https://<api>/api/health # git_sha 가 새 커밋인지 ``` ## Key Insights - **API 에러는 "요청이 실패했다"이지 "아무 일도 안 일어났다"가 아니다.** 쓰기 API 는 부분적으로 성공할 수 있고, 502 는 게이트웨이 계층이라 백엔드가 어디까지 갔는지 말해주지 않는다. - **원본(ref)이 메타데이터(PR 레코드)보다 진실이다.** GitHub UI/`gh pr view` 는 PR 레코드를 보여주는데, 실제로 배포를 결정하는 것은 `origin/main` 의 ref 다. - `mergeStateStatus: BEHIND` 같은 부수 신호가 오해를 강화한다 — 그건 이미 전진한 main 기준으로 다시 계산된 값이다. - 다음에 먼저 확인할 것: **`git log origin/main`.** PR 상태 API 를 다시 부르지 마라. ## Red Flags - 머지 명령이 5xx/timeout 인데 CI 는 전부 green 이었다 - PR 은 열려 있는데 `git log origin/main` 에 그 PR 번호의 커밋이 있다 - 머지 직후 `mergeStateStatus` 가 `BEHIND` 로 바뀌었다 - 재시도하려는 충동 — 그 전에 ref 를 봐라 ## 같은 착시, 다른 원인 — `--delete-branch` 의 로컬 정리 단계 (2026-08-12, PR #742) ``` $ gh pr merge 742 --squash --delete-branch failed to run git: fatal: 'main' is already used by worktree at '/…/bsvibe-app/main' ``` 머지 실패로 읽힌다. **머지는 됐다** (`gh pr view 742 → state=MERGED`). `--delete-branch` 는 원격 머지가 끝난 **뒤** 로컬 정리를 한다 — 로컬 브랜치를 지우려면 먼저 다른 브랜치로 옮겨야 하므로 `git checkout main` 을 시도한다. bare + worktree 레이아웃(`.bare` / `main` / `wt/*`)에서는 `main` 이 이미 다른 worktree 에 체크아웃돼 있어 그 checkout 이 거부되고, gh 가 그 exit code 를 그대로 뱉는다. 즉 **머지 명령의 비-0 종료가 머지 실패를 뜻하지 않는다** — 502 든 로컬 git 이든 같다. 확인 순서는 동일하다: 재시도 전에 `gh pr view <N> --json state,mergeCommit` 과 `git log origin/main` 을 먼저 본다. 정리는 손으로: ```bash git -C <main-worktree> fetch -q origin && git merge --ff-only origin/main git worktree remove wt/<name> && git branch -D <name> ```
عرض على GitHub