제가 코딩을 늦게 시작하고 처음 팀 프로젝트에 들어갔을 때, 가장 낯설었던 단어가 바로 이 "PR 올렸어요"라는 말이었어요. "피알? 홍보(Public Relations)를 올린다고?" 진지하게 그렇게 생각했습니다. 회의 시간에 누군가 "제가 PR 올렸으니 봐주세요" 하는데, 저는 속으로 '무슨 보도자료를 냈다는 거지?' 하고 어리둥절했죠. 그런데 알고 보니 이건 홍보와 아무 상관이 없고, 우리가 함께 코드를 만드는 방식 전체를 떠받치는 아주 다정한 습관이더라고요.
앞선 글에서 우리는 브랜치 이야기를 했습니다. 원본(main)을 건드리지 않고 내 작업용 복사본을 하나 떠서 거기서 마음껏 실험하는 거였죠. 실수해도 원본은 멀쩡하니 마음 편히 도전할 수 있었어요. 자, 그럼 이제 브랜치에서 작업을 다 끝냈다고 칩시다. 기능도 잘 돌아가고, 테스트도 통과했어요. 뿌듯하죠. 그런데 여기서 질문 하나. 이걸 이제 어떻게 main에 합칠까요?
답부터 말하면, 바로 합치지 않습니다. 아무리 내 코드가 완벽해 보여도, 브랜치의 작업을 곧장 main에 밀어 넣는 건 위험한 습관이에요. 대신 "제 작업 여기 다 됐는데, 합치기 전에 한 번 봐주시겠어요?" 하고 정중하게 요청서를 냅니다. 이 요청서가 바로 PR(Pull Request)이고, 동료가 그걸 읽고 피드백을 주는 과정이 코드 리뷰예요. 오늘은 이 두 가지를, 겁먹지 않게 아주 천천히 풀어드릴게요. 읽고 나면 "PR 올렸어요"가 얼마나 따뜻한 말인지 아시게 될 거예요.
PR은 내가 쓴 원고를 정식 원고 뭉치에 끼워 넣기 전에, 편집자에게 "검토 요청서"와 함께 내미는 것입니다. 그리고 코드 리뷰는 그 편집자가 빨간 펜으로 "여기 오타 있어요", "이 문장은 이렇게 하면 어때요?" 하고 달아주는 다정한 교정입니다.
혼자 일기장을 쓸 때는 편집자가 필요 없죠. 아무렇게나 써도 나만 보니까요. 하지만 여러 사람이 함께 한 권의 책을 만들 때는, 아무리 잘 쓴 원고라도 다른 눈이 한 번 훑어주는 게 훨씬 안전합니다. 오탈자, 앞뒤 안 맞는 설정, 다른 챕터와 충돌하는 내용 — 정작 쓴 사람은 못 보는 걸 남은 금방 봐요. PR과 리뷰는 그 "다른 눈"을 우연에 맡기지 않고 제도로 만든 것뿐이에요. 저도 이걸 이해하고 나서야 팀에서 마음이 편해졌습니다. "아, 내가 실수해도 누군가 걸러주는구나" 하는 안심 말이에요.
1. PR이 뭔가요 — "제 브랜치, 합쳐주세요" 요청서
PR은 Pull Request의 줄임말입니다. 우리말로 억지로 옮기면 "당겨가기 요청" 정도인데, 솔직히 이 직역이 오히려 헷갈려요. "뭘 당겨간다는 거야?" 싶죠. 그래서 저는 의미로 풀어서 외웠습니다. "제 브랜치에 있는 변경사항을, main(혹은 다른 목표 브랜치)으로 당겨가서 합쳐주세요"라는 공식 요청. 이렇게요.
그런데 왜 브랜치에서 바로 main에 합치면 안 되냐고요? 기술적으로는 얼마든지 가능해요. 명령어 한 줄이면 됩니다. 하지만 "가능하다"와 "그래도 된다"는 다르죠. main은 실제 서비스가 돌아가는, 모두가 믿고 딛고 서는 바닥입니다. 여기에 검토 안 된 코드가 들어가면, 나 하나의 실수가 팀 전체와 사용자에게 번져요. 그래서 우리는 스스로 "잠깐, 바로 넣지 말고 한 번 봐달라고 하자"는 관문을 만들어 둡니다. 급할수록, 자신 있을수록 오히려 이 관문이 나를 지켜줘요. 자신만만할 때가 제일 위험하거든요.
왜 하필 "당겨간다(pull)"는 표현일까요? 관점의 문제예요. 내 입장에서는 "내 걸 밀어 넣는다(push)" 같지만, 원본(main)을 관리하는 쪽 입장에서는 "저 브랜치에 있는 걸 우리 쪽으로 당겨온다"가 되거든요. 받는 사람 기준의 표현인 거죠. 처음엔 이 방향이 헷갈렸는데, "요청을 받는 쪽 시선"이라고 생각하니 자연스러워졌어요.
중요한 건 PR이 단순한 "합쳐주세요" 버튼이 아니라는 점이에요. 만약 그냥 버튼 하나였다면 이렇게 자세히 설명할 것도 없죠. PR은 하나의 무대입니다. 그 무대 위에 이런 것들이 한꺼번에 올라옵니다.
- 내가 무엇을, 왜 바꿨는지 설명하는 글
- 정확히 어떤 파일의 어떤 줄이 바뀌었는지 한눈에 보여주는 변경점(diff)
- 동료들이 특정 줄에 콕 집어 남기는 코멘트와 토론
- 자동으로 돌아가는 검사(CI) — 테스트 통과했는지, 규칙 어겼는지
- 준비가 다 되면 실제로 합치는 Merge 버튼
즉 PR 화면 하나만 열면 "이 변경은 어떤 내용이고, 누가 뭐라고 했고, 기계 검사는 통과했나"를 전부 볼 수 있어요. 정보가 흩어져 있지 않고 한자리에 모여 있는 거죠. 그래서 나중에 "이 코드 왜 이렇게 됐지?" 싶을 때 그 PR을 다시 찾아보면 당시의 맥락이 고스란히 남아 있습니다. "아, 그때 이런 이유로 이렇게 바꿨고, 김대리가 이런 우려를 했었구나" 하고요. 이게 시간이 지날수록 정말 큰 자산이 됩니다.
비유를 다시 붙여볼게요. 출판사에 원고를 넘길 때, 그냥 파일만 툭 던지지 않죠. "이번 챕터는 3장을 다시 썼고, 인물 A의 대사를 다듬었습니다. 특히 12쪽 대화가 자연스러운지 봐주세요" 하는 커버레터를 함께 냅니다. PR의 제목과 설명이 딱 그 커버레터예요. 커버레터가 정성스러우면 편집자도 어디를 봐야 할지 알고 기분 좋게 읽기 시작하죠. 반대로 파일만 덜렁 오면 "이걸 어디부터 보라는 거야" 하고 한숨부터 나오고요. PR도 똑같습니다.
2. 브랜치에서 PR까지 — 전체 그림 한 장
말로만 하면 흐릿하니, 작업이 어떤 순서로 흘러가는지 그림으로 봐두면 좋습니다. 코드를 만들어 main에 안착시키기까지의 여정은 대략 이런 흐름이에요.
작업용 복사본
변경 저장
봐주세요 요청
사람+기계 검토
main에 합침
왼쪽에서 오른쪽으로, 내 브랜치에서 시작해 결국 main에 안전하게 도착하는 여정입니다. 하나씩 짚어볼게요. 먼저 브랜치를 떠서 거기서 작업하고, 작업 단위마다 커밋으로 저장을 남깁니다. 어느 정도 완성되면 PR을 열어 "봐주세요" 하고 요청하죠. 그러면 사람 리뷰어와 기계 검사(CI)가 함께 그 변경을 살펴봅니다. 문제가 없으면 마지막으로 Merge 버튼을 눌러 main에 합칩니다.
가운데의 "리뷰·CI" 단계가 오늘 글의 핵심이에요. 이 단계가 없으면 검토되지 않은 코드가 곧바로 main으로 들어가는데, 그건 교정 안 본 원고를 그대로 인쇄기에 넣는 것과 같습니다. 오탈자투성이 책이 서점에 깔리는 거죠. 위험할 뿐 아니라, 한번 인쇄되고 나면(=운영 서버에 배포되고 나면) 되돌리는 데 훨씬 큰 비용이 듭니다. 그래서 우리는 "합치기 전에" 이 관문을 꼭 통과시키는 거예요.
참고로 이 흐름은 앞뒤 글과 자연스럽게 이어집니다. 브랜치를 어떻게 나눌지는 브랜치 전략 글에서, 이 전체 그림이 왜 "자동으로 검사하고 배포하는" 문화의 일부인지는 CI/CD 이야기에서 다뤘어요. 오늘은 그 가운데 토막, 즉 "합치기 직전"에 벌어지는 일을 확대해서 봅니다.
3. PR의 구성요소 — 화면을 하나하나 뜯어봅시다
처음 PR 화면을 열면 버튼과 탭과 숫자가 많아 보여서 압도당하기 쉬운데요, 사실 핵심 몇 개만 알면 됩니다. 낯선 계기판도 자주 보면 익숙해지듯이요. 하나씩 뜯어볼게요.
| 구성요소 | 무엇인가 | 비유 |
|---|---|---|
| 제목 / 설명 | 이 변경이 뭘 하는지, 왜 했는지 적는 글 | 원고에 붙이는 커버레터 |
| 변경 파일 (Files changed) | 어떤 파일의 어떤 줄이 바뀌었는지 색으로 표시 | 빨간 펜용 교정지 |
| 커밋 목록 (Commits) | 이 PR에 담긴 저장 지점들의 이력 | 원고 수정 일지 |
| 리뷰어 (Reviewers) | 봐달라고 지정한 동료들 | 담당 편집자 |
| 코멘트 (Conversation) | 줄 단위 / 전체에 남기는 대화 | 여백에 적은 메모 |
| 체크 (Checks / CI) | 자동 검사 통과 여부 (통과 / 실패) | 맞춤법 검사기 |
| Merge 버튼 | 모든 게 준비되면 실제로 합치는 버튼 | "인쇄 넘김" 도장 |
여기서 변경 파일(diff)을 조금만 더 자세히 볼게요. 리뷰의 90%가 여기서 일어나거든요. diff라는 말은 difference, 즉 "차이"의 줄임입니다. 바뀌기 전과 후를 나란히 비교해서 보여주는 화면이에요. diff 화면은 바뀐 줄을 색으로 표시합니다. 지운 줄은 보통 빨간 배경에 - 기호가, 추가한 줄은 초록 배경에 + 기호가 붙어요. 예를 들면 이런 식입니다.
- price = 1000← 빨간색, "이 줄을 지웠다"+ price = 1200← 초록색, "이 줄로 바꿨다"
이 두 줄을 함께 읽으면 "가격을 1000에서 1200으로 바꿨구나" 하고 알 수 있죠. 비개발자분들도 이 색깔 규칙만 알면 diff를 읽을 수 있어요. "빨강은 뺀 것, 초록은 넣은 것." 딱 이거면 절반은 이해한 겁니다. 나머지는 그 줄이 무슨 뜻인지인데, 그건 코드를 짠 사람이 설명에 적어두거나 리뷰 코멘트로 물어보면 돼요. 그러니 diff 화면이 알록달록하다고 겁먹지 마세요. 신호등 색 읽듯 편하게 보시면 됩니다.
또 하나, 커밋 목록은 원고 수정 일지 같은 거라 했죠. 한 PR 안에 커밋이 여러 개 들어 있을 수 있어요. "일단 기능 추가 → 오타 수정 → 리뷰 반영" 이런 식으로 여러 번 저장한 흔적이 쌓입니다. 리뷰어는 최종 diff를 보기도 하고, 필요하면 커밋 하나하나를 따라가며 "어떤 순서로 생각했는지"를 읽기도 해요.
PR, 실제로 이렇게 엽니다
화면만 설명하니 여전히 붕 뜬 느낌일 수 있어 실제 여는 과정을 짧게 짚어볼게요. 어렵지 않습니다. 브랜치에서 작업하고 저장(커밋)한 다음, 그 브랜치를 GitHub에 올리면(push) 되는데요, 딱 세 단계입니다.
브랜치를 GitHub에 올린다
내 컴퓨터에서만 있던 브랜치를 git push로 GitHub에 밀어 올립니다. 그래야 남들도 볼 수 있어요. 원고를 서랍에서 꺼내 편집부 책상에 올려놓는 거죠.
"Compare & pull request" 버튼을 누른다
브랜치를 올리면 GitHub이 알아서 "이 브랜치로 PR 만드실래요?" 하고 초록 버튼을 띄워줍니다. 못 봤어도 "Pull requests" 탭에서 새로 만들 수 있어요.
제목·설명을 적고 만든다
어느 브랜치를 어디(보통 main)에 합칠지 고르고, 커버레터(제목·설명)를 적은 뒤 "Create pull request"를 누르면 끝. 이제 무대가 열렸습니다.
겁먹으실까 봐 미리 말씀드리면, 이 화면들은 전부 한글 안내가 붙어 있진 않아도 버튼 위치가 늘 비슷해서 두어 번 해보면 손에 익습니다. 저도 처음엔 초록 버튼 하나 누르는 데 심호흡을 했는데, 지금은 눈 감고도 해요. 처음이 어색할 뿐이에요.
4. 코드 리뷰가 뭔가요 — 그리고 왜 하나요
코드 리뷰는 말 그대로 동료가 내 코드를 읽고 피드백을 주는 것입니다. "여기 이렇게 하면 특정 상황에서 버그 나요", "이 부분은 나중에 헷갈릴 것 같은데 이름을 바꾸면 어때요?", "오, 이거 깔끔하네요 👍" 같은 코멘트들이죠. PR 화면의 diff 옆에 줄 단위로 콕 집어 남길 수도 있고, 전체적인 소감을 맨 아래에 종합해서 남길 수도 있어요.
왜 굳이 이걸 할까요? 처음엔 저도 "다 만든 걸 왜 또 검사받아야 하지, 시간 낭비 아닌가, 나를 못 믿나" 싶었어요. 살짝 자존심도 상했고요. 그런데 몇 달 겪어보니 이유가 아주 분명하더라고요. 리뷰가 있을 때와 없을 때를 나란히 놓고 보면 차이가 확 옵니다.
👍 리뷰가 있을 때
- 버그를 합치기 전에 잡는다 (터지고 고치는 것보다 훨씬 쌈)
- 다른 사람이 코드를 이해하니 지식이 공유된다
- "이렇게 하면 더 낫다"가 오가며 품질이 오른다
- 왜 이렇게 짰는지 기록이 PR에 남는다
- 혼자여도 셀프 리뷰로 실수를 스스로 발견
👎 리뷰가 없을 때
- 버그가 그대로 main으로 → 운영에서 터짐
- 그 코드를 아는 사람이 작성자 한 명뿐
- 제각각 스타일로 짜서 나중에 아무도 못 읽음
- "이거 왜 이래?"에 답할 맥락이 사라짐
- 내 오타·실수를 아무도 못 걸러줌
이 중에서 "버그를 합치기 전에 잡는다"는 게 눈에 가장 잘 보이는 이득이에요. 소프트웨어에서 버그는 늦게 발견될수록 고치는 비용이 커집니다. 리뷰 단계에서 발견하면 코멘트 한 줄로 끝나지만, 그게 운영 서버까지 나가서 고객이 겪고 나면 사과 메일에, 긴급 배포에, 밤샘까지 이어지죠. 저도 리뷰에서 "여기 이 경우 처리 빠진 것 같은데요?" 한마디에 큰 사고를 면한 적이 여러 번이에요. 그때마다 리뷰해준 동료가 정말 고마웠습니다.
두 번째로 큰 건 "지식 공유"예요. 내가 짠 코드를 최소 한 명이 더 읽는다는 건, 그 부분을 아는 사람이 팀에 최소 두 명이 된다는 뜻입니다. 내가 휴가를 가거나 퇴사해도 팀이 멈추지 않아요. 반대로 리뷰 없이 나 혼자만 아는 코드가 쌓이면, 그 부분은 언젠가 아무도 손대기 무서운 "지뢰밭"이 됩니다.
세 번째, "품질이 오른다"도 무시 못 할 이득이에요. 리뷰를 주고받다 보면 "아, 이런 방법도 있었네" 하는 배움이 계속 쌓입니다. 저는 코딩 늦게 시작한 사람이라, 솔직히 책이나 강의보다 동료의 리뷰 코멘트에서 배운 게 더 많아요. 내 코드를 두고 "여기는 이렇게 하면 더 안전해요" 하는 구체적인 조언은, 어떤 교재보다 몸에 착 붙거든요. 리뷰는 공짜 개인 과외이기도 한 셈입니다. 반대로 리뷰어 입장에서도 남의 코드를 읽으며 "이 사람은 이렇게 푸는구나" 하고 배웁니다. 그래서 리뷰는 주는 사람, 받는 사람 모두가 성장하는 드문 활동이에요.
특히 목록 마지막 줄, "혼자여도"를 강조하고 싶어요. 많은 분들이 "저는 혼자 하는데 리뷰가 무슨 소용이에요?" 하시는데, 셀프 리뷰라는 게 있습니다. PR을 열어놓고 diff를 처음 보는 사람처럼 위에서 아래로 쭉 읽어보는 거예요. 신기하게도, 코드를 짤 때의 나와 diff를 읽는 나는 마음가짐이 다릅니다. 짤 때는 "이게 되게 하자"에 몰두하지만, 읽을 때는 "이거 이상한데?"가 보여요. 그래서 셀프 리뷰에서 오타, 지우려다 만 실험 코드, 깜빡한 부분이 정말 많이 걸립니다. 지금의 내가 3개월 뒤의 나를 위해 남기는 편지라고 생각하면 딱이에요.
5. 좋은 PR 만드는 법 — 리뷰어를 배려하는 습관
리뷰를 잘 받으려면, 사실 리뷰어가 읽기 좋게 PR을 만드는 게 먼저예요. 좋은 원고를 내야 좋은 교정을 받듯이요. 아무리 실력 좋은 편집자라도 뒤죽박죽인 원고 뭉치 앞에서는 힘을 못 씁니다. 제가 몸으로 배운 원칙들을 순서대로 정리해봤습니다.
작게 쪼개기
한 PR에 기능 하나만 담으세요. 1000줄짜리 거대한 PR은 리뷰어가 읽다 지쳐서 대충 "LGTM(좋아 보여요)" 하고 넘깁니다. 사람 집중력에는 한계가 있거든요. 작으면 오히려 꼼꼼히 봐줘요. 원고도 한 챕터씩 넘기는 게 서로 편하죠.
제목을 명확히
"수정함", "작업" 같은 제목 말고 "로그인 실패 시 에러 메시지 표시"처럼 한 줄로 뭘 했는지 알 수 있게 적으세요. 나중에 PR 목록을 쭉 봤을 때, 제목만으로 내용이 그려져야 좋은 제목입니다.
설명에 '왜'를 적기
무엇을 바꿨는지는 diff에 이미 나와요. 그러니 설명에는 왜 이렇게 했는지, 어떤 문제를 풀려는 건지를 적으세요. 화면이 바뀌는 작업이면 스크린샷을 붙이면 최고입니다. 리뷰어가 앱을 직접 안 켜봐도 결과를 보니까요.
셀프 리뷰 먼저
남에게 부탁하기 전에 내가 먼저 diff를 처음 보는 눈으로 훑어보세요. 디버깅용 출력, 오타, 실험 잔여물, 주석 처리한 옛 코드가 여기서 대부분 걸립니다. 남의 시간을 아끼는 최소한의 예의예요.
리뷰어가 볼 곳을 안내
"특히 결제 처리 부분(payment.js)을 중점적으로 봐주세요"나 "이 부분은 제가 확신이 없어서 의견 구합니다" 한 줄만 적어도 리뷰어가 힘을 어디에 쏟을지 알게 됩니다.
참고로 좋은 PR 설명이 대략 어떻게 생겼는지 감을 드릴게요. 거창할 필요 없어요. 이런 뼈대면 충분합니다.
무엇: 로그인 실패 시 아무 반응이 없던 문제를 고쳤습니다.
왜: 사용자가 비밀번호를 틀려도 화면이 그대로라 "먹통인가?" 하고 오해했어요.
어떻게: 실패 시 "아이디 또는 비밀번호를 확인해 주세요" 문구를 띄웁니다.
봐주실 곳: 특히 에러 메시지 문구가 적절한지 봐주세요. (스크린샷 첨부)
6. 좋은 리뷰 태도 — 사람이 아니라 코드에게
이번엔 반대로, 남의 PR을 리뷰하는 입장이 됐을 때입니다. 여기서 태도가 정말 중요해요. 코드 리뷰는 기술이기 전에 사람 사이의 대화거든요. 잘못하면 상처를 주고 관계를 망치지만, 잘하면 팀이 함께 자랍니다. 같은 지적도 어떻게 말하느냐에 따라 완전히 달라져요.
제가 지키려 애쓰는 몇 가지가 있어요. 대단한 게 아니라, 사람 대 사람으로 당연한 것들입니다.
- 사람이 아니라 코드에 말한다. "왜 이렇게 짰어요?"(사람을 탓하는 느낌)가 아니라 "이 부분은 이렇게 하면 어떨까요?"(코드 얘기)로 방향을 돌리세요.
- 질문형으로 부드럽게. "이거 틀렸어요"보다 "혹시 이 경우엔 문제 없을까요?"가 대화를 엽니다. 정말 내가 잘못 본 걸 수도 있고요.
- 근거와 대안을 함께. 지적만 툭 하지 말고 "왜냐하면 이런 상황에서~", "예를 들면 이렇게 하면~"을 붙이면 받는 사람도 납득하고 배웁니다.
- 칭찬도 리뷰다. "이 처리 깔끔하네요 👍", "이 이름 잘 지으셨어요" 한 줄이 상대에게 큰 힘이 됩니다. 저는 이걸 일부러 챙겨요. 지적 사이사이에 칭찬이 있으면 전체 분위기가 확 달라집니다.
그리고 리뷰 문화에서 자주 쓰는 두 단어를 소개할게요. 익혀두면 리뷰가 한결 부드러워집니다. 영어권 개발 문화에서 넘어온 표현인데, 우리나라 팀에서도 그대로 많이 씁니다.
| 표현 | 뜻 | 느낌 |
|---|---|---|
| Nit: | "nitpick(사소한 트집)"의 줄임. 아주 작은 지적이라는 표시 | "이건 꼭 안 고쳐도 되는데, 굳이 말하자면~" |
| Suggestion: | 강요가 아닌 제안임을 밝히는 말 | "이렇게 해도 좋을 것 같아요, 선택은 자유예요" |
여기에 하나 더, 요즘 팀들이 많이 쓰는 표현으로 "이건 제 취향일 수도 있어요" 같은 완충 문구도 있어요. 객관적으로 틀린 게 아니라 스타일 차이일 때 이렇게 미리 밝혀두면, 받는 사람이 "이건 강제가 아니구나" 하고 마음 편히 취사선택할 수 있죠. 반대로 정말 중요한 문제, 예컨대 보안 구멍이나 데이터가 날아갈 수 있는 부분은 완충 문구 없이 분명하게 짚어줘야 합니다. "이건 꼭 고쳐야 해요, 안 그러면 이런 사고가 날 수 있어요" 하고요. 가벼운 건 가볍게, 무거운 건 무겁게. 이 강약 조절이 좋은 리뷰어의 감각입니다.
이 두 단어의 마법은, 지적의 무게를 미리 알려준다는 데 있어요. "Nit: 여기 띄어쓰기요"라고 하면 받는 사람은 "아 이건 가벼운 거구나, 시간 나면 고치면 되겠다" 하고 편하게 받아들입니다. 반대로 아무 표시 없이 무게가 큰지 작은지 모를 지적이 스무 개 달리면, 받는 쪽은 전부 심각한 문제처럼 느껴져 압도당하죠. 같은 말을 해도 상대의 마음 부담을 확 줄여주는, 아주 실용적인 배려입니다.
7. 리뷰 코멘트 종류와 승인 흐름
리뷰를 마칠 때 리뷰어는 보통 세 가지 중 하나를 선택합니다. 이 세 가지의 차이를 알면 "이 PR이 지금 합쳐질 수 있는 상태인지"를 바로 알 수 있어요.
| 선택 | 의미 | 언제 쓰나 |
|---|---|---|
| Comment (의견만) | 승인도 반대도 아닌, 그냥 의견 | "참고하세요" 정도의 가벼운 말 |
| Approve (승인) | "저는 합쳐도 좋다고 봅니다" 👍 | 봤고, 괜찮고, 진행해도 될 때 |
| Request changes (변경 요청) | "이건 고친 다음에 합쳐요" | 합치기 전 꼭 바꿔야 할 게 있을 때 |
많은 팀이 여기에 규칙을 겁니다. 대표적으로 "리뷰어 한 명 이상이 Approve하고, 자동 검사(CI)도 통과해야 Merge 버튼이 열린다" 같은 거예요. 이걸 브랜치 보호 규칙이라고 해요. 원고로 치면 "편집장 사인 없이는 인쇄 못 넘김" 같은 안전장치죠. 덕분에 아무리 급해도, 심지어 팀장이라도, 검토 없는 코드가 main에 들어가지 않습니다. 사람은 실수하고 급할 땐 판단이 흐려지니, 규칙으로 못을 박아두는 거예요.
실제로 한 PR이 어떻게 흘러가는지 짧은 장면으로 그려볼게요. 제가 "로그인 에러 메시지" PR을 올립니다. 곧 CI가 돌아 테스트 통과 표시가 뜨고, 김대리가 들어와 "여기 비밀번호가 빈 칸일 때도 이 메시지가 뜨나요?"라고 질문형 코멘트를 남기며 Request changes를 겁니다. 제가 "앗, 빈 칸 처리를 빠뜨렸네요. 감사합니다" 하고 고쳐 같은 브랜치에 다시 커밋하면, PR이 최신으로 갱신되죠. 김대리가 바뀐 부분만 다시 보고 "이제 좋네요 👍" 하며 Approve로 바꾸면, 잠겨 있던 Merge 버튼이 열립니다. 제가 그 버튼을 누르면 드디어 main에 안착. 이 한 바퀴가 코드 리뷰의 전형적인 리듬이에요.
변경 요청(Request changes)을 받으면 어떻게 하냐고요? 절대 상처받을 필요 없어요. 오히려 리뷰어가 시간을 들여 꼼꼼히 봤다는 증거입니다. 요청받은 부분을 고쳐서 같은 브랜치에 다시 커밋하면, PR이 알아서 업데이트됩니다. 새 PR을 또 만들 필요가 없어요. 이게 처음엔 신기했는데, PR은 "브랜치"를 가리키고 있어서 그 브랜치에 새 커밋이 올라가면 PR도 자동으로 최신 상태가 되거든요. 그러면 리뷰어는 바뀐 부분만 다시 보고 Approve로 바꿔주면 끝입니다. 대화가 한 바퀴 돌고 마무리되는 거죠.
8. AI와 자동화 — 기계가 도와주는 리뷰
요즘 PR 무대에는 사람만 있는 게 아닙니다. 기계도 한 자리를 당당히 차지하고 있어요. 다만 여기서는 과장 없이, 지금 실제로 쓰이는 만큼만 이야기할게요. 기술 글에서 제일 경계해야 할 게 "이제 사람은 필요 없다" 같은 호들갑이니까요.
첫째, CI(자동 검사)입니다. PR을 올리면 미리 정해둔 테스트가 자동으로 좌르륵 돌아가서 "통과" 또는 "실패"를 붙여줘요. 사람이 일일이 "테스트 돌려봤어요?" 하고 묻지 않아도 되죠. 만약 실패가 뜨면 그 상태로는 보통 Merge가 막힙니다. 이 자동화의 배경 이야기는 CI/CD 이야기에서 다뤘고, GitHub에서 이걸 실제로 굴리는 도구는 GitHub Actions 글에서 이어서 설명합니다. 지금은 "PR을 올리면 기계가 알아서 테스트를 돌려준다" 정도만 알면 충분해요.
둘째, AI 코드 리뷰입니다. 최근에는 AI가 PR을 읽고 "이 부분에 이런 버그 가능성이 있어요", "이 이름은 헷갈릴 수 있어요", "여기 예외 처리가 빠진 것 같아요" 같은 코멘트를 자동으로 달아주는 도구들이 나왔어요. 사람 리뷰어가 놓치기 쉬운 것을 한 번 먼저 걸러주는 보조 역할이죠. 특히 단순 실수나 흔한 패턴은 AI가 꽤 잘 잡습니다. 다만 이건 어디까지나 보조라는 걸 잊지 마세요. AI가 "괜찮다"고 해도 그게 우리 서비스 맥락에 맞는지는 사람이 봐야 하고, AI가 지적한 게 오히려 틀릴 때도 있어요. "AI가 그러던데요" 하고 무조건 따르는 건 위험합니다.
셋째, 조금 더 나아가서 코딩 에이전트가 아예 PR을 만들어주기도 합니다. "이 이슈 좀 고쳐줘" 하면 AI가 코드를 짜서 PR로 올리고, 사람은 그 PR을 리뷰만 하는 흐름이에요. 여기서도 최종 판단은 사람 몫입니다. 오히려 AI가 코드를 많이 만들어낼수록, 그걸 검토하는 "리뷰" 능력이 더 중요해지는 셈이죠. 이 이야기는 GitHub 코딩 에이전트 글에서 따로 자세히 다룹니다.
정리하면, 자동화의 역할은 "사람이 안 해도 되는 반복 검사"를 대신 맡아주는 거예요. 테스트를 매번 손으로 돌리고, 코드 스타일을 눈으로 하나하나 확인하는 건 지치고 실수하기 쉬운 일이죠. 그런 건 기계에게 맡기고, 사람은 "이 변경이 우리 서비스에 정말 맞는 방향인가", "사용자 입장에서 이게 자연스러운가" 같은 판단이 필요한 부분에 집중하는 겁니다. 기계와 사람이 각자 잘하는 걸 나눠 맡는 거예요. 그래서 자동화가 늘어난다고 리뷰가 사라지는 게 아니라, 리뷰의 무게중심이 "단순 확인"에서 "진짜 판단"으로 옮겨가는 것에 가깝습니다.
여기서 꼭 기억할 것 하나. AI와 자동화가 아무리 좋아져도, 그것들이 올라타는 무대가 바로 PR이라는 사실은 변하지 않습니다. PR이라는 검토 요청서 문화를 알아두면, 앞으로 어떤 도구가 나와도 자연스럽게 그 위에 올라탈 수 있어요. 그래서 오늘 배운 게 유행 타지 않는 기초입니다.
9. 초보가 흔히 하는 실수 & 해결
제가 직접 저질렀거나, 옆에서 자주 본 실수들입니다. 부끄럽지만 다 제가 한 번씩은 해본 것들이에요. 미리 알아두면 크게 데일 일이 줄어듭니다.
👎 이런 실수
- 거대한 PR: 2주치 작업을 한 번에 올려 리뷰 불가
- 설명 없는 PR: 제목은 "수정", 설명은 텅 빔
- 감정적 리뷰: "이걸 코드라고 짰어요?" 같은 말
- 리뷰 방치: 부탁받은 PR을 며칠씩 안 봄
- 지적에 방어부터: 모든 코멘트에 반박
- 도장 리뷰: 안 보고 습관적으로 Approve만
👍 이렇게 해결
- 기능·수정 단위로 작게 쪼개서 여러 PR로
- 제목은 한 줄 요약, 설명엔 '왜'와 스크린샷
- 코드에 대한 질문형·제안형 표현으로
- 리뷰는 반나절~하루 안에. 막히면 "언제까지 볼게요" 한마디라도
- 일단 고맙다 → 이해 → 반영/설명 순서로
- 못 볼 것 같으면 솔직히 다른 사람에게 넘기기
특히 "리뷰 방치"는 팀 전체를 조용히 느리게 만드는 병입니다. 리뷰를 기다리는 사람은 다음 작업으로 못 넘어가고 발이 묶여요. PR 하나가 며칠씩 방치되면, 그 사이 main이 바뀌어 충돌이 생기기도 하고, 작성자는 "내 작업이 무시당하나" 하는 서운함까지 쌓입니다. 완벽하게 볼 시간이 없으면, "지금 회의라 오후에 볼게요"라는 한 줄만 남겨도 상대는 훨씬 마음이 놓입니다. 리뷰는 실력보다 속도와 배려가 먼저인 경우가 많아요.
반대편 극단인 "도장 리뷰"도 조심하세요. 바쁘다고 코드를 제대로 안 보고 Approve만 누르는 습관인데, 이게 반복되면 리뷰 제도 자체가 유명무실해집니다. 봐줬다고 믿었는데 아무도 안 본 코드가 나가는 거죠. 정 볼 시간이 없으면 차라리 "지금 제가 급해서 꼼꼼히 못 봤어요, 다른 분 리뷰도 받아보시면 좋겠어요"라고 솔직히 말하는 편이 낫습니다.
10. 자주 묻는 질문 (FAQ)
Q. 혼자 개발하는데 PR이 꼭 필요해요?
A. 필수는 아니지만, 강력히 추천합니다. 혼자여도 PR을 열고 셀프 리뷰를 하면 오타와 실수가 놀랄 만큼 걸립니다. 무엇보다 "무엇을, 왜 바꿨는지" 기록이 남아서, 몇 달 뒤에 "이 코드 내가 왜 이렇게 했지?" 싶을 때 과거의 내가 남긴 설명이 구원해 줘요. 미래의 나를 위한 편지라고 생각하세요. 저는 1인 프로젝트에서도 이 습관 덕을 톡톡히 봤습니다.
Q. 리뷰에서 지적을 받으면 자꾸 상처가 돼요.
A. 아주 자연스러운 감정이에요. 저도 그랬습니다. 딱 하나만 기억하세요. 리뷰는 당신이 아니라 코드를 향한 것입니다. "이 코드 이렇게 하면 좋겠다"는 "당신이 못났다"가 절대 아니에요. 오히려 누군가 시간 내서 꼼꼼히 봐줬다는 건 당신 코드를 진지하게 대했다는 뜻입니다. 무관심보다 훨씬 고마운 일이에요. 시간이 지나 실력이 붙으면, 이 지적들이 다 나를 키운 자양분이었다는 걸 알게 됩니다.
Q. PR을 올렸는데 아무도 안 봐줘요.
A. 조용히 기다리지만 마세요. 다들 자기 일에 바빠서 못 본 것일 가능성이 큽니다. 리뷰어를 명시적으로 지정하고, 채팅으로 "○○님, PR 하나 봐주실 수 있을까요? 급하진 않아요" 하고 부드럽게 알리세요. 그래도 PR이 너무 크면 다들 부담스러워 미루게 되니, 작게 쪼개는 것도 좋은 방법입니다. "리뷰 잘 받는 것"도 실력의 일부예요.
Q. 리뷰어 의견에 동의가 안 되면 무조건 따라야 하나요?
A. 아니에요. 리뷰는 대화지 명령이 아닙니다. 동의가 안 되면 "이 부분은 이런 이유로 이렇게 뒀는데, 어떻게 생각하세요?"라고 근거를 들어 정중히 답하세요. 서로 설득하다 보면 더 나은 답이 나오거나, 둘 다 몰랐던 걸 발견하기도 합니다. 감정 대결이 아니라 "더 나은 코드 찾기"라는 같은 목표를 향한 대화라는 걸 기억하세요. 정 결론이 안 나면 제3의 동료 의견을 구하는 것도 좋습니다.
Q. LGTM이 무슨 뜻이에요?
A. "Looks Good To Me"의 줄임으로, "제가 보기엔 좋아 보여요, 합쳐도 될 것 같아요"라는 승인 표현입니다. 리뷰 문화에서 아주 흔히 쓰여요. 비슷하게 "SGTM(Sounds Good To Me)"도 있고요. 다만 앞서 말한 "도장 리뷰"처럼 코드를 제대로 안 보고 습관적으로 LGTM만 다는 건 곤란합니다. 진짜로 봤을 때, 마음을 담아 쓰는 말이에요.
11. 마무리 — 오늘의 체크리스트
여기까지 오셨다면, 이제 "PR 올렸어요"라는 말이 더는 낯설지 않으실 거예요. 저처럼 홍보로 오해하는 일도 없을 거고요. 오늘 우리가 나눈 이야기를 체크리스트로 정리하고 마칩니다. 나중에 실제로 PR을 올릴 때 한 번씩 짚어보세요.
- ✅ PR = 브랜치를 main에 합치기 전 내는 "봐주세요 요청서"다
- ✅ PR 무대에는 설명·diff·커밋·코멘트·CI·Merge가 모여 있다
- ✅ diff는 "빨강은 뺀 것, 초록은 넣은 것"만 알면 읽힌다
- ✅ 리뷰는 버그를 미리 잡고, 지식을 나누고, 기록을 남긴다
- ✅ 좋은 PR은 작고, 제목이 명확하고, 설명에 '왜'가 적혀 있다
- ✅ 좋은 리뷰는 사람이 아니라 코드에게, 질문형으로, 칭찬도 함께
- ✅ Comment / Approve / Request changes의 차이를 안다
- ✅ AI·CI는 훌륭한 보조지만, 최종 판단은 사람 몫이다
- ✅ 혼자여도 셀프 리뷰는 미래의 나를 위한 편지다
PR과 코드 리뷰는 기술이라기보다 함께 일하는 예의에 가깝습니다. "합치기 전에 한 번 봐줄래요?"라는 이 짧은 문장 하나가, 서로의 실수를 걸러주고 같이 성장하게 만들어요. 처음엔 번거로워 보여도, 익숙해지면 이것 없이 협업하는 게 오히려 불안해집니다. 저도 그랬어요. 지금은 리뷰 없이 main에 뭔가 들어간다고 생각하면 등골이 서늘할 정도예요. 그러니 겁먹지 말고 오늘 딱 하나, 작은 PR 하나만 셀프 리뷰와 함께 올려보세요. 그 한 걸음이 시작입니다.
다음 글에서는 PR을 올리면 자동으로 테스트를 돌려주는 그 "기계 검사"의 정체, GitHub Actions를 손에 잡히게 풀어드릴게요. 오늘 배운 CI 체크가 실제로 어떻게 굴러가는지, 무엇을 어떻게 적어두면 기계가 알아서 일해주는지, 그 무대 뒤를 함께 보러 갑시다. 이 시리즈 전체 지도가 궁금하시면 DevOps 시리즈 개요부터 다시 보셔도 좋아요.
(2026년 8월 기준 작성 — 화면·정책은 바뀔 수 있으니 공식 문서를 함께 확인하세요.)
← 기술 블로그 목록으로