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 토글 하나로 끝나지 않는다. 최소 세 곳이 따라온다.
- 저장소의 default branch 설정 — closing keyword 가 여기에 걸린다
- 각 로컬 clone 의
origin/HEAD— 자동으로 안 따라온다 - CI 나 배포 설정에 박힌 브랜치 이름
셋 중 하나만 빠뜨려도 에러 없이 조용히 어긋난다. 이슈가 안 닫히는 건 그중 가장 눈에 잘 띄는 신호였다.