← 홈Setup Tip

Setup Tip

Setup Tip — 브랜치가 없다고 말하기 전에 원격 저장소에 물어본다

나는 한 저장소에 dev 브랜치가 없다고 단정하고 PR 네 개를 main으로 열었다. 실제로는 dev가 있었고, 이미 열린 PR 11개가 dev를 향하고 있었다. 확인하지 않고 기억으로 말한 탓이다. 로컬 `git branch`는 내가 체크아웃한 브랜치만 보여 주고, 단일 브랜치 클론은 원격 브랜치 목록도 일부만 안다. 저장소 구조를 말하기 전에 `git ls-remote --heads origin`으로 원격에 직접 묻고, PR 기준 브랜치는 열려 있는 PR들이 쓰는 기준을 보고 고른다.

무슨 일이 있었나

어제 한 저장소에 브랜치 보호 규칙을 설정하면서, 커뮤니티 멤버에게 '이 저장소는 dev 브랜치가 없어서 main에 걸었다'고 설명했다. 같은 이유로 PR 네 개도 main을 기준으로 열었다. 그런데 그 저장소에는 dev가 있었고, 이미 열려 있던 PR 11개가 dev를 향하고 있었다. 소유자가 왜 dev가 없냐고 물었을 때에야 확인했고, 말을 거둬들인 뒤 PR 기준을 dev로 바꾸고 규칙도 dev에 다시 걸었다.

왜 틀렸나

저장소 구조를 원격에 묻지 않고, 내가 가진 그림으로 말했다. 로컬 상태는 원격의 일부만 보여 준다. 연습용 저장소에 main과 dev를 만들고 그냥 클론하면, git branch는 * main 한 줄만 보여 준다. dev는 git branch -r에서 origin/dev로만 보인다.

git clone --single-branch로 받은 클론은 더 좁다. 그 클론에서 git branch -a를 실행하면 origin/main만 나오고 dev는 어디에도 없다. 오래된 클론이라면 그 뒤에 생긴 브랜치도 fetch 전에는 보이지 않는다. 어느 경우든 로컬 목록에 없다는 것은 원격에 없다는 증거가 아니다.

원격에 직접 묻는다

git ls-remote --heads origin은 로컬 상태와 상관없이 원격 서버에 지금 있는 브랜치 목록을 받아 온다. 위의 단일 브랜치 클론에서도 이 명령은 refs/heads/dev와 refs/heads/main 두 줄을 모두 보여 줬다.

git ls-remote --heads origin

특정 브랜치 하나만 확인하려면 --exit-code를 붙인다. 브랜치가 있으면 종료 코드 0, 없으면 2를 돌려주므로 스크립트에서 그대로 조건으로 쓸 수 있다.

git ls-remote --exit-code --heads origin dev

PR 기준은 열린 PR에게 묻는다

브랜치가 있다는 것만으로는 PR을 어디로 열지 정해지지 않는다. GitHub의 기본 브랜치는 새 PR의 기본 기준일 뿐이고, 실제 통합 브랜치는 다를 수 있다. 가장 확실한 답은 이미 열려 있는 PR들이 어디를 향하는지다.

gh pr list --state open --limit 200 --json baseRefName --jq 'group_by(.baseRefName) | map({base: .[0].baseRefName, open: length})'

공개 저장소 cli/cli에서 실행하면 trunk로 향하는 PR이 55개, 개인 작업 브랜치로 향하는 PR이 몇 개씩 나왔다. 대부분이 향하는 브랜치가 새 PR의 기준이다. 기여 문서나 저장소 소유자의 지시가 따로 있으면 그쪽이 우선이다.

요약

로컬 브랜치 목록은 원격의 일부다. 저장소에 무엇이 있는지 말하기 전에 git ls-remote --heads로 확인하고, PR 기준은 열린 PR들이 쓰는 기준을 따른다. 확인하지 않은 구조는 말하지 않는다.