좋은 PR이 뭔데?

매번 셀프 체크를 위한 PR만 올렸었다. 근데, 뭐 좋은 PR이라는게 있나?

Jun Noh

방금 깃 브런치 전략 글 정리하다가, 자연스럽게 따라오는 다음 질문이 있다.

“그래서 좋은 PR 이 뭔데?”

이것도 답을 못 한다.

PR 의 본질적인 기능 — 다른 사람의 검토 — 은 사실 단 한 번도 제대로 받아본 적이 없다. 중소기업에서 1명이 여러 프로젝트의 특정 부분을 혼자 맡는 식이라, 그럴 일이 없었다.

물론 셀프 체크를 위해서 PR 을 가끔 올리긴 한다. 근데 그마저도 매번 브런치 따기가 귀찮아서 미루고 미루다, 수천 줄짜리 PR 을 올리는 식이다.

이게 무슨 체크가 되겠나.

그래서 겸사겸사 브런치 전략 정리하는 김에, 좋은 PR 이란 게 뭔지도 같이 생각해봤다.

암튼, 정리해보자.

PR 이 일단 뭐냐

정의부터:

Pull Request 는 “내 브랜치를 대상 브랜치에 합쳐주세요” 라는 공식 요청이다.

단순한 머지 버튼이 아니다. 변경 내용을 모아놓고 그 위에서 검토하고 토론하는 하나의 공간이자 단위 다.

그래서 “좋은 PR” 은 두 가지를 동시에 만족해야 한다.

  1. 검토하기 좋은 단위로 만들어졌는가 (작성자의 책임)
  2. 검토 과정이 제대로 작동하는가 (리뷰어와 프로세스의 책임)

코드 리뷰가 왜 있는가

좋은 PR 을 이해하려면, 리뷰가 왜 존재하는지부터 알아야 한다. 흔히 “버그 잡기” 로만 생각하는데 그건 일부일 뿐.

  • 버그 조기 발견: 운영 나가기 전에 잡는 비용이 압도적으로 싸다
  • 지식 공유: 특정 코드를 한 사람만 아는 상태(“버스 지수 1”)를 줄임
  • 일관성 유지: 팀 코딩 스타일 / 설계 관습을 코드에 스며들게 함
  • 공동 소유 의식: “내 코드” 가 아니라 “우리 코드” 가 됨. 품질 책임이 분산되면서 동시에 공유됨
  • 설계 피드백: 구현 전엔 안 보이던 더 나은 접근을 리뷰에서 발견하기도 함

이 목적들을 기억 안 하면, 리뷰는 “변수명 가지고 싸우는 자리” 로 변질된다.

작성자 측 — 좋은 PR 의 조건

리뷰 품질의 절반 이상은 PR 올리는 사람이 결정한다.

1. 작게 쪼갠다 — 가장 중요

diff 가 수백 줄 넘어가면 리뷰어는 집중력 잃고 결국 “대충 보고 승인” 누른다. 큰 기능은 의미 있는 단위로 여러 PR 로 나눈다.

  • 작은 PR 은 리뷰 빠름, 머지 빠름, 충돌 적음, 문제 생겨도 원인 찾기 쉬움
  • “큰 기능을 어떻게 작게 쪼개느냐” 가 실력이다. 기반 작업 → 핵심 로직 → UI 연결 식으로

2. 하나의 PR 은 하나의 목적만

“로그인 기능 추가 + 김에 한 리팩토링 + 발견한 오타 수정” 을 한 PR 에 섞으면, 리뷰어가 뭐에 집중해야 할지 흐려진다.

  • 기능과 리팩토링 분리. 리팩토링은 동작 변화 없어야 하고 기능 추가는 동작 변화 있다. 섞으면 “이 변화가 의도된 건지 부작용인지” 구분 안 됨.
  • 무관한 수정(오타, 포맷)도 별도 PR.

3. 설명에 “왜” 를 쓴다

무엇은 diff 가 말해준다. 설명에는 를 쓴다.

  • 어떤 문제를 풀려고 했나
  • 왜 이 방식을 택했나, 고려했다가 버린 대안은 뭐였나
  • 관련 이슈/티켓 링크
  • UI 변경이면 스크린샷/영상
  • 리뷰어가 특히 봐줬으면 하는 부분, 본인이 확신 없는 부분 명시

좋은 설명은 리뷰어의 컨텍스트 진입 비용을 크게 줄인다.

4. 올리기 전에 Self-review

PR 올린 직후, 본인이 diff 처음부터 끝까지 한 번 읽는다.

  • 디버깅용 출력(console.log, print), 주석 처리해둔 코드, 오타, 빠뜨린 파일 — 상당수가 여기서 잡힌다
  • 리뷰어 시간 아끼는 가장 기본적인 예의

5. CI 통과시킨 상태로 올린다

빌드 실패, 테스트 실패, 린트 오류 난 상태로 리뷰 요청 안 한다.

기계가 잡을 수 있는 건 기계가 먼저 잡게 하고, 사람은 그 다음을 본다.

리뷰어 측 — 좋은 리뷰의 조건

1. 빨리 본다

PR 오래 방치되면 작성자는 컨텍스트 잃고, 그 위에 다른 작업 쌓여 충돌 커진다. 리뷰는 우선순위 높은 일로 취급하는 게 팀 전체 속도에 이롭다.

2. 사람이 아니라 코드를 비판한다

  • “너 왜 이렇게 짰어” (X) → “이 부분은 이렇게 하면 이런 이점이 있을 것 같다” (O)
  • 리뷰는 상대를 깎는 자리가 아니라 코드를 더 낫게 만드는 자리

3. 코멘트의 중요도를 표시한다

모든 코멘트가 같은 무게는 아니다. 많은 팀이 접두어 컨벤션 쓴다.

  • nit: (nitpick) — 사소한 취향. 안 고쳐도 무방
  • suggestion: — 제안. 고려해보면 좋음
  • question: — 단순 질문. 이해가 안 가서 묻는 것
  • blocking: (또는 별도 표시) — 이건 고쳐야 머지 가능

무게를 구분하면, 사소한 취향 코멘트 때문에 PR 이 불필요하게 막히는 일이 사라진다.

4. 스타일은 사람이 보지 않는다

들여쓰기, 따옴표, 줄 길이 같은 거는 린터/포매터(Prettier, ESLint, Black) 한테 맡긴다. 사람은 로직과 설계에 집중. 스타일 두고 리뷰에서 논쟁하는 건 시간 낭비.

5. 칭찬도 코멘트다

잘 짠 부분에는 “이 접근 좋네요” 남긴다. 리뷰가 지적만 쌓이는 곳이 되면 사람들이 PR 올리기를 두려워하게 되고, PR 이 점점 커지는 (= 리뷰 받는 횟수 줄이려는) 악순환이 생긴다.

머지 규칙 — 자동화로 강제하기

성숙한 조직은 “좋은 PR” 을 사람의 선의가 아니라 설정으로 강제한다 (예: GitHub branch protection rule).

  • 최소 N명의 승인 없이는 머지 불가
  • CI(빌드/테스트/린트) 통과해야만 머지 가능
  • main 에 직접 push 금지 — 반드시 PR 거치게
  • 머지 방식 통일 (squash merge 등으로 히스토리 정리)

이렇게 해두면 “급해서 그냥 올렸다” 가 구조적으로 불가능해진다.

나쁜 PR 의 전형 — 피해야 할 것

  • 거대한 PR: 수천 줄 diff. 사실상 검토 불가능 → 형식적 LGTM 부름
  • 목적이 섞인 PR: 기능 + 리팩토링 + 잡다한 수정 → 뭐가 의도된 변화인지 분간 불가
  • 설명 없는 PR: 제목만 “수정” → 리뷰어가 의도 추측해야 함
  • CI 깨진 채 올린 PR: 기계가 잡을 걸 사람에게 떠넘김
  • 오래 방치된 PR: 컨텍스트 소실 + 충돌 누적

1인 개발자면 어떻게 해야 하나

리뷰어가 없으면 코드 리뷰 “절차” 자체의 의미는 약하다. 근데 핵심 정신은 가져올 수 있다.

  • Self-diff 습관: 머지 전 git diff 로 변경분을 통째로 다시 읽는다. “타인의 눈” 을 흉내 내는 짧은 과정이, 급하게 짜서 바로 올렸다가 터지는 사고의 상당수를 막는다.
  • 시간차 검토: 작지 않은 변경은 짜고 바로 머지하지 말고 하루 묵혔다 다시 본다. 어제 안 보이던 게 보인다.
  • 커밋 메시지를 미래의 나에게 쓰는 편지로: 혼자여도 “왜 이렇게 했는지” 를 남겨두면, 나중에 본인이 레거시 만질 때 비용이 줄어든다.

반대로 1인 단계에서 굳이 흉내 낼 필요 없는 거: 다단계 승인 프로세스, 형식적인 PR 템플릿 강제. 이런 건 “여러 사람” 이라는 전제가 있어야 비용이 정당화된다.

근데 솔직히 본인이 안 한 거랑 비슷한 항목들이 좀 있다.

특히 self-diff 습관과 커밋 메시지를 미래의 나한테 쓰는 편지로 — 이 두 개는 좀 챙겨야겠다 싶다. 본인이 짠 코드를 6개월 뒤 본인이 다시 볼 때 “왜 이렇게 했지?” 라고 생각하는 빈도가 늘고 있는데, 커밋 메시지에 “왜” 를 적어두면 그 비용이 진짜 줄긴 할 거다.

마치며

좋은 PR 의 본질은 한 줄로 줄이면:

리뷰어(또는 미래의 나)가 최소한의 비용으로 변경의 의도와 안전성을 판단할 수 있는 단위.

앞에서 적었듯 셀프 체크용 PR 가끔 올리긴 하는데 — approve 누르는 사람도 코멘트 다는 사람도 다 본인인 데다, 그마저도 수천 줄짜리면 체크가 될 리가 없다.

그래도 1인 개발자한테는 사실상 “미래의 나” 가 리뷰어니까, 작게 쪼개고 “왜” 라도 적어두는 정도는 챙기는 게 맞겠다 싶다.

더 좋은 1인용 방법이 있는지는 차근차근 알아봐야겠다.

암튼 정리 한 번 해보고 싶었다.

마침.

다른 글 보기