처음 코드 리뷰를 받으면 코멘트 하나하나가 평가처럼 느껴집니다. 수정 요청이 여러 개 달리면 내가 많이 못했나 하는 생각이 쉽게 듭니다. 그런데 리뷰는 사람을 깎는 절차가 아니라, 코드의 상태와 팀의 기준을 맞추는 대화입니다.
이 글에서는 그 대화를 해석하는 쪽에 무게를 둡니다. 리뷰 코멘트는 짧게 쓰이는 경우가 많아서, 문장 그대로 읽으면 무엇을 하라는 것인지 알기 어렵습니다. 자주 나오는 문구들을 실제 행동으로 옮기는 방법을 정리했습니다.
코멘트는 나에게 붙은 것이 아니라 줄 번호에 붙은 것입니다
리뷰 코멘트는 파일과 줄 번호에 붙습니다. 이 사실이 생각보다 많은 것을 설명합니다. 리뷰어는 화면에서 그 줄을 보다가 걸리는 지점에 메모를 남긴 것이고, 그 메모의 수신자는 코드입니다. 코멘트가 열 개라면 걸리는 줄이 열 개였다는 뜻이지, 실력을 열 단계로 평가했다는 뜻이 아닙니다.
코멘트가 많아지는 이유도 대체로 실력과 무관합니다. 변경 줄이 많으면 코멘트도 많아집니다. 처음 보는 영역을 건드렸으면 팀의 관례를 알려 주는 코멘트가 붙습니다. 리뷰어가 그 파일을 오래 관리했다면 남들이 모르는 사연이 코멘트로 나옵니다. 셋 다 내가 못해서 생긴 일이 아닙니다.
그래서 첫 반응으로 필요한 것은 방어도 사과도 아니고, 번역입니다. 이 문장이 요구하는 구체적인 행동이 무엇인지로 바꿔 읽는 일입니다.
자주 나오는 문구와 그 뜻
아래는 리뷰에서 반복해서 보게 되는 문장들입니다. 짧아서 차갑게 읽히지만, 요구하는 행동은 대부분 분명합니다.
REVIEW COMMENTS
1. "여기 매직 넘버가 있네요."
2. "이 함수 좀 긴 것 같습니다."
3. "nit: 변수명이요."
4. "이 값이 없으면 어떻게 되나요?"
5. "이 부분 왜 이렇게 하셨는지 궁금합니다."
6. "테스트 하나만 추가해 주실 수 있을까요?"
7. "이거 이번 PR에서 꼭 해야 할까요?"
8. LGTM
문장 길이와 요구 강도는 비례하지 않습니다. 가장 짧은 코멘트가 가장 큰 수정을 요구하는 경우도 흔합니다.
1번은 코드에 박혀 있는 숫자나 문자열을 이름 있는 상수로 빼 달라는 요청입니다. if retry < 3의 3이 무엇을 뜻하는지 코드만 보고는 알 수 없다는 지적입니다. 상수 이름을 붙이면 그 자체가 설명이 됩니다.
2번은 길이 자체보다 하는 일의 개수를 말하는 경우가 많습니다. 함수 안에서 값을 가져오고, 변환하고, 저장까지 한다면 세 덩어리로 나눌 수 있다는 뜻입니다. 줄 수를 줄이는 것이 목적이 아니므로, 어느 경계에서 나눌지를 함께 물어보면 대화가 빨라집니다.
3번의 nit은 사소하다는 표시입니다. 리뷰어가 스스로 "이건 취향에 가깝다"고 밝힌 것이므로, 반영해도 되고 이유를 대며 그대로 둬도 됩니다. 이 표시가 붙은 코멘트를 두고 오래 고민할 필요는 없습니다.
4번은 질문 형태지만 실제로는 버그 지적입니다. 값이 비어 있는 경우를 처리하지 않았다는 뜻이고, 요구되는 행동은 그 경우를 처리하거나 처리하지 않아도 되는 이유를 답으로 적는 것입니다. 리뷰에서 "~면 어떻게 되나요"는 대체로 이 형태입니다.
5번은 정말로 궁금한 경우와, 다른 방법이 있다고 생각하는 경우가 섞여 있습니다. 먼저 의도를 설명하고 대안이 있는지 되물으면 양쪽 다 해결됩니다. 설명해 보다가 스스로 이상하다고 느끼면 그게 답입니다.
6번은 그 변경이 나중에 조용히 깨질 수 있다고 본다는 뜻입니다. 어떤 상황을 걱정하는지 물어보면 어떤 테스트를 써야 할지가 바로 정해집니다. 작은 케이스로 시작하는 테스트 정도면 대개 충분합니다.
7번은 범위를 줄이자는 제안입니다. 지금 PR에서 빼고 별도로 처리하자는 뜻이므로, 후속 작업으로 적어 두고 이번에는 넘어가는 것이 맞습니다.
8번의 LGTM은 looks good to me의 줄임말로 승인 표시입니다. 성의 없는 반응이 아니라 통과 신호입니다.
답글은 세 가지 형태면 충분합니다
모든 코멘트에 긴 답을 달 필요는 없습니다. 답글은 동의, 보류, 반대 셋 중 하나이고 각각 문장 형태가 정해져 있습니다.
REPLIES
[동의]
"맞습니다. 상수로 빼고 RETRY_LIMIT으로 이름 붙였습니다. (a3f21c)"
[보류]
"동의합니다. 다만 이 리팩터링이 결제 쪽까지 번져서
이번 PR에서는 두고 이슈 #142로 올렸습니다."
[반대]
"여기는 의도한 동작입니다. 이 시점에는 값이 항상 채워져
있어서 검사를 넣으면 절대 실행되지 않는 분기가 생깁니다.
제가 놓친 경로가 있을까요?"
[모르겠음]
"무슨 말씀인지 정확히 이해하지 못했습니다.
어느 쪽이 더 나은지 짧은 예시를 하나 주실 수 있을까요?"
동의에는 반영한 커밋을, 보류에는 다음 처리 위치를, 반대에는 근거와 되묻는 문장을 함께 붙입니다. 모르겠다는 답도 정상적인 답입니다.
세 형태 모두 공통점이 있습니다. 다음에 무슨 일이 일어나는지가 문장 안에 들어 있습니다. 고쳤다면 어디를 고쳤는지, 미뤘다면 어디로 옮겼는지, 반대라면 무엇을 근거로 하는지입니다. 리뷰어 입장에서 가장 곤란한 답글은 "넵" 하나만 달려 있고 무엇이 어떻게 바뀌었는지 알 수 없는 경우입니다.
반대할 때는 되묻는 문장을 붙이는 편이 좋습니다. 내가 아는 범위가 리뷰어보다 좁을 수 있고, 실제로 놓친 경로가 있으면 그 자리에서 드러납니다. 질문을 붙여 두면 반대가 대립이 아니라 확인 절차가 됩니다. 질문을 다듬는 방법은 더 나은 질문을 만드는 법과 같은 요령을 씁니다.
리뷰어가 항상 옳은 것은 아닙니다
여기까지 읽으면 코멘트를 잘 받아들이는 쪽으로만 기울 수 있어서, 반대편도 적어 둡니다.
컨텍스트를 모르고 남기는 지적이 있습니다. 리뷰어는 변경된 줄만 보는 경우가 많습니다. 그 함수가 왜 그렇게 생겼는지, 어떤 장애 때문에 그 검사가 들어갔는지는 화면에 나오지 않습니다. 그래서 이미 검토를 마친 사항이 다시 지적으로 올라오기도 합니다. 이럴 때 필요한 것은 수정이 아니라 배경 설명이고, 같은 지적이 반복된다면 그 설명을 주석이나 PR 본문에 남겨 두는 편이 낫습니다.
취향을 규칙처럼 말하는 경우도 있습니다. 삼항 연산자를 쓸지 말지, 짧은 함수를 여러 개 둘지 하나로 묶을지 같은 문제에는 정답이 없습니다. 다만 팀 규칙으로 정해진 것인지 개인 선호인지는 구분할 수 있습니다. 문서나 린터 설정에 있으면 규칙이고, 없으면 선호입니다. 선호를 규칙처럼 말하는 코멘트에는 "컨벤션에 있는 내용인지 확인하고 싶습니다"라고 되물으면 됩니다. 이 질문은 공격이 아니라 기준을 명확히 하자는 요청입니다.
모든 지적을 즉시 반영하려다 PR이 비대해지는 문제가 가장 흔한 역효과입니다. 코멘트를 따라가다 보면 리팩터링이 옆 파일로 번지고, 변경 파일이 늘어나고, 그러면 리뷰가 더 어려워져서 코멘트가 또 붙습니다. 리뷰가 끝나지 않는 상태에 들어갑니다. 코멘트를 받았을 때 "이번 PR의 목적과 관련 있는가"를 한 번 걸러야 합니다. 관련이 없으면 후속 작업으로 적고, 그 사실을 답글로 알리는 것까지가 처리입니다.
리뷰받기 쉬운 PR을 만드는 준비
리뷰 경험의 상당 부분은 코멘트를 받기 전에 결정됩니다.
PR을 작게 만듭니다. 한 PR에 하나의 목적만 담습니다. 기능 추가와 정리 작업이 섞이면 리뷰어는 두 종류의 판단을 동시에 해야 하고, 그러면 읽는 속도가 느려집니다. 파일 이름 변경이나 포매팅처럼 diff를 크게 만드는 작업은 따로 분리합니다.
설명문에 무엇을 봐 달라고 적습니다. 변경 내용을 나열하는 것보다, 어디를 집중해서 봐 달라고 지목하는 편이 훨씬 유용합니다. "재시도 로직이 맞는지 확인 부탁드립니다", "A와 B 방식 중 A를 골랐는데 의견 있으시면 알려 주세요" 같은 문장 한두 줄이면 리뷰의 방향이 달라집니다. 스스로 걸린다고 느낀 부분을 먼저 적어 두면, 지적으로 올라오기 전에 논의로 바뀝니다.
커밋을 읽을 수 있게 나눕니다. 리뷰어가 커밋 단위로 따라 읽을 수 있으면 큰 변경도 소화됩니다. 커밋을 나누는 감각은 첫 주에 익히는 깃에서 시작합니다.
다음 리뷰에서 해 볼 것
- PR 설명 맨 위에 봐 달라고 부탁할 지점을 한 줄 적습니다.
- 코멘트를 받으면 요구하는 행동 한 문장으로 옮겨 적어 봅니다.
- 답글은 동의, 보류, 반대, 모르겠음 중 하나로 형태를 정하고 씁니다.
- 반영한 코멘트에는 커밋 해시를 같이 남깁니다.
- 이번 PR의 목적과 무관한 지적은 이슈로 옮기고 그 사실을 답글에 적습니다.
같은 종류의 지적이 세 번 이상 반복되면 개인 체크리스트로 옮깁니다. 다음 PR을 올리기 전에 그 목록만 훑어도 코멘트 수가 눈에 띄게 줄어듭니다. 리뷰에서 배우는 것의 대부분은 개별 코멘트가 아니라, 반복되는 패턴 쪽에 있습니다.
코멘트를 받고 아무 말 없이 코드만 고쳐서 다시 올리는 것입니다. 리뷰어는 자기가 남긴 지적이 반영됐는지 다시 전부 확인해야 하고, 반영되지 않은 것이 의도인지 누락인지 알 수 없습니다. 고쳤다면 고쳤다고, 안 고쳤다면 왜 안 고쳤는지 한 줄씩 답을 답니다. 답글 다는 시간이 리뷰 한 바퀴를 줄여 줍니다.
리뷰는 합격과 불합격을 가르는 심사가 아니라, 코드를 사이에 두고 주고받는 짧은 대화입니다. 대화인 이상 듣는 법만큼 답하는 법도 배우게 됩니다.