PR 에 Closes #N 을 써도 이슈가 안 닫힌다면 — base 가 기본 브랜치인지 본다

GitHub 의 closing keyword 는 PR 의 base 가 저장소 기본 브랜치일 때만 동작한다. develop 기반 워크플로로 옮기는 중이면 조용히 무시된다.

PR 본문에 Closes #16 을 적고 머지했다.

gh pr merge --squash

머지는 됐다. 이슈는 안 닫혔다.

$ gh issue view 16 --json state -q .state
OPEN

오타도 아니고 권한 문제도 아니었다. 키워드 자체가 무시된 것이다.

원인 — base 브랜치 조건

GitHub 의 closing keyword(Closes / Fixes / Resolves 등)로 이슈가 자동으로 닫히려면 조건이 하나 붙는다. PR 의 base 브랜치가 그 저장소의 기본 브랜치여야 한다.

내 상황이 정확히 여기 걸렸다. main 기반에서 develop 기반 워크플로로 옮기는 중이라 feature PR 의 base 를 develop 으로 잡았는데, 저장소 Settings 상의 default branch 는 아직 main 이었다. GitHub 입장에서 develop 은 그냥 브랜치 하나일 뿐이라 키워드를 무시했다.

혼동을 키우는 건 PR 화면이다. 이슈와 PR 의 연결 자체는 그대로 표시된다. “linked issue” 배지도 붙는다. 그래서 화면만 보면 잘 설정된 것처럼 보이고, 머지 후에야 안 닫혔다는 걸 알게 된다.

동작이 이렇게 정해진 이유는 납득이 간다. 기본 브랜치가 아닌 곳에 머지된 건 아직 “제품에 반영됐다”고 볼 수 없다. long-lived 브랜치에 머지될 때마다 이슈가 닫히면 릴리스 전에 이슈 트래커가 텅 비어버린다.

해결 두 가지

① 기본 브랜치를 실제로 바꾼다

주 워크플로가 develop 이라면 이게 맞다.

gh repo edit <owner>/<repo> --default-branch develop

이후로는 develop 으로 머지되는 PR 의 Closes #N 이 정상 동작한다. 딸려오는 것도 많다.

  • git clone 시 기본 체크아웃 브랜치
  • PR 생성 시 기본으로 선택되는 base
  • 저장소 첫 화면에 보이는 브랜치
  • worktree 도구들이 “기본 브랜치에서 분기”할 때 쓰는 기준

② 안 바꾸고 매번 수동으로 닫는다

전환이 확정되지 않았거나 릴리스 브랜치 전략상 main 을 기본으로 둬야 한다면, 머지 후 직접 닫는 수밖에 없다.

gh issue close <N> --comment "PR #<M> develop 머지 완료. base 가 기본 브랜치가 아니라 자동 close 안 됨."

코멘트를 남겨두면 나중에 “왜 이 이슈만 수동으로 닫혔지”를 다시 조사하지 않아도 된다.

확인 방법

지금 값부터 본다.

gh repo view <owner>/<repo> --json defaultBranchRef -q .defaultBranchRef.name

여기 나온 이름과 PR 의 base 가 같으면 키워드가 동작하고, 다르면 무시된다. 판단은 이 한 줄로 끝난다.

바꾼 뒤에 한 번 더 밟는 함정

기본 브랜치를 바꿔도 로컬 clone 은 모른다. refs/remotes/origin/HEAD 는 clone 시점에 한 번 설정되고 자동 갱신되지 않는다.

그래서 기본 브랜치를 바꾼 직후, 기존 clone 에서 “기본 브랜치에서 새 브랜치 분기”를 하면 여전히 옛 브랜치에서 갈라진다. 조용히 몇 주 전 코드 위에서 작업을 시작하게 된다.

git remote set-head origin -a

자세한 증상과 확인 절차는 기본 브랜치를 바꿨는데 새 worktree 가 옛 브랜치에서 분기될 때에 적었다.

정리

기본 브랜치 전환은 Settings 토글 하나로 끝나지 않는다. 최소 세 곳이 따라온다.

  1. 저장소의 default branch 설정 — closing keyword 가 여기에 걸린다
  2. 각 로컬 clone 의 origin/HEAD — 자동으로 안 따라온다
  3. CI 나 배포 설정에 박힌 브랜치 이름

셋 중 하나만 빠뜨려도 에러 없이 조용히 어긋난다. 이슈가 안 닫히는 건 그중 가장 눈에 잘 띄는 신호였다.