16. Pull Request 심화 — 코드 리뷰와 협업

🎯 이 장의 목표
  • Pull Request(PR)가 무엇이고 왜 협업의 핵심인지 이해한다
  • PR을 열고, 리뷰하고, 병합하는 전체 흐름을 익힌다
  • 협업자(collaborator)를 추가하고 보호 브랜치를 설정한다
  • 이슈(Issue)로 작업을 추적한다

16.1 Pull Request란 무엇인가?

지금까지는 내 변경을 그냥 git push로 main에 바로 올렸습니다. 하지만 팀에서는 그렇게 하지 않습니다. "내 브랜치의 변경을 main에 합쳐도 될까요? 검토해주세요"라고 요청하고, 동료가 확인(리뷰)한 뒤 합칩니다. 이 요청이 Pull Request(PR)입니다.

flowchart TD
    F["🌿 내 feature 브랜치"]
    PR["📬 PR 생성<br/>리뷰 요청"]
    R["👀 동료가 코드 검토<br/>+ 코멘트"]
    M["✅ 승인 → main에 병합"]
    F --> PR --> R --> M
    classDef branch fill:#dbeafe,stroke:#2563eb,color:#1e40af
    classDef pr fill:#fef3c7,stroke:#d97706,color:#92400e
    classDef review fill:#f3e8ff,stroke:#9333ea,color:#6b21a8
    classDef merge fill:#dcfce7,stroke:#16a34a,color:#166534
    class F branch
    class PR pr
    class R review
    class M merge
💡 팁
왜 "Pull" Request인가? 내가 main에 직접 밀어 넣는(push) 게 아니라, "내 변경을 당겨가(pull) 주세요"라고 저장소 관리자에게 요청하는 형태이기 때문입니다. (GitLab에서는 같은 것을 Merge Request, MR라고 부릅니다. 이름만 다르고 개념은 같습니다.)

PR이 주는 이점

  • 코드 리뷰: 합치기 전에 동료가 버그·개선점을 발견
  • 토론 기록: 왜 이렇게 바꿨는지 대화가 영구 보존
  • 품질 게이트: CI(13장)가 자동으로 테스트를 돌려 검증
  • 지식 공유: 다른 사람의 코드를 보며 팀 전체가 성장

16.2 PR 전체 흐름 (Step by Step)

가장 일반적인 PR 워크플로우입니다.

BASH
# 1. main 최신화
git switch main
git pull

# 2. 작업용 브랜치 생성
git switch -c feature/add-login

# 3. 작업하고 커밋
echo "login code" > login.js
git add login.js
git commit -m "Add login feature"

# 4. 원격에 브랜치 push
git push -u origin feature/add-login
  1. GitHub에서 PR 생성: push 후 GitHub 저장소에 가면 "Compare & pull request" 버튼이 뜹니다. 또는 12장의 gh pr create로 터미널에서 바로 만들 수 있습니다.
  1. PR 작성: 제목, 설명(무엇을·왜 바꿨는지), 리뷰어 지정.
  1. 리뷰 → 수정 → 승인 → 병합
  1. 정리: 병합 후 브랜치 삭제.
BASH
git switch main
git pull
git branch -d feature/add-login

16.3 PR 리뷰하기

리뷰어는 PR 페이지의 Files changed 탭에서 변경을 줄 단위로 봅니다.

  • 특정 줄에 마우스를 올려 + 를 누르면 그 줄에 코멘트를 남길 수 있습니다.
  • 리뷰를 마치며 세 가지 중 하나를 선택합니다.
리뷰 결정의미
Comment의견만 남김 (승인/거부 아님)
Approve승인 (병합해도 좋음)
Request changes수정 요청 (이대로는 병합 불가)

터미널에서도 가능합니다(12장).

BASH
gh pr review 42 --approve
gh pr review 42 --request-changes --body "테스트 추가 부탁드려요"

작성자가 코멘트에 따라 추가 커밋을 push하면, PR에 자동으로 반영됩니다. PR은 "브랜치"를 가리키므로, 그 브랜치에 커밋이 쌓이면 PR도 함께 갱신됩니다.

16.4 PR 병합 방식 3가지

병합할 때 GitHub은 세 가지 방식을 제공합니다. (8·9장의 개념과 연결됩니다.)

방식결과언제
Create a merge commit병합 커밋 생성, 모든 커밋 보존작업 이력을 그대로 남기고 싶을 때
Squash and merge브랜치의 모든 커밋을 하나로 합쳐 병합자잘한 커밋을 깔끔히 정리할 때 (가장 흔함)
Rebase and merge커밋들을 main 위에 직선으로 재배치병합 커밋 없이 직선 이력을 원할 때
BASH
gh pr merge 42 --squash --delete-branch
💡 팁
Squash and merge가 실무에서 가장 인기 있습니다. feature 브랜치에서 "WIP", "오타 수정" 같은 지저분한 커밋이 여러 개여도, main에는 "Add login feature" 하나의 깔끔한 커밋으로 들어가기 때문입니다.

16.5 협업자(Collaborator) 추가하기

개인 저장소에 다른 사람이 직접 push하려면 협업자로 초대해야 합니다.

  1. 저장소 → Settings → Collaborators
  2. Add people으로 GitHub 사용자명/이메일 입력
  3. 초대받은 사람이 이메일/알림에서 수락

협업자가 되면 그 사람도 브랜치를 push하고 PR을 열 수 있습니다. (포크 없이 직접 기여 — 12장의 포크 방식과 대비됩니다. → 17장)

16.6 보호 브랜치(Protected Branch) 설정

기본적으로는 승인 없이도 main에 병합이 가능합니다. 하지만 중요한 브랜치(main)는 규칙으로 보호해야 사고를 막습니다.

  1. 저장소 → Settings → Branches → Add branch ruleset (또는 Branch protection rule)
  2. 대상 브랜치: main
  3. 주요 옵션:
규칙효과
Require a pull request before mergingmain 직접 push 금지, PR 필수
Require approvals병합 전 N명의 승인 필요
Require status checks to passCI(테스트) 통과해야 병합 가능
Require conversation resolution모든 리뷰 코멘트 해결 후 병합

이 설정 후에는 승인 없는 PR은 병합 버튼이 비활성화됩니다. 즉 누군가 한 명은 반드시 코드를 봐야 main에 들어갑니다.

💡 팁
보호 브랜치 + 필수 CI는 실무 협업의 표준입니다. "검증 안 된 코드가 main에 절대 못 들어가게" 만드는 안전장치입니다.

16.7 이슈(Issue)로 작업 추적하기

이슈는 "할 일·버그·아이디어"를 기록하고 토론하는 공간입니다. 코드를 담지 않는 일종의 게시판입니다.

  • Issues 탭 → New issue
  • 제목 + 설명(재현 절차, 기대 동작 등) 작성
  • Labels(bug, enhancement...), Assignees(담당자), Milestone(목표 시점) 지정
BASH
# 터미널에서 (12장)
gh issue create --title "로그인 버튼 작동 안 함" --label bug --assignee "@me"
gh issue list --state open

PR과 이슈 연결하기

커밋 메시지나 PR 설명에 특정 키워드를 쓰면, PR이 병합될 때 이슈가 자동으로 닫힙니다.

CODE
Fixes #17
Closes #23
Resolves #5

예: PR 설명에 Fixes #17이라고 쓰면, 그 PR이 main에 병합되는 순간 17번 이슈가 자동으로 Close됩니다. 작업과 추적이 깔끔하게 연결됩니다.

16.8 공개 저장소에서 배우기

유명 오픈소스 저장소의 PR을 구경하는 것은 최고의 학습법입니다. 실제 개발자들이 어떻게 변경을 설명하고, 리뷰하고, 토론하는지 그대로 볼 수 있습니다. 관심 있는 프로젝트의 Pull requests 탭과 Issues 탭을 둘러보세요. 좋은 PR 설명과 리뷰 문화를 자연스럽게 익히게 됩니다.

16.9 이 장에서 배운 것 (요약)

  • PR = "내 브랜치를 main에 합쳐달라"는 리뷰 요청 (GitLab은 MR)
  • 흐름: 브랜치 push → PR 생성 → 리뷰/코멘트 → 승인 → 병합 → 브랜치 정리
  • 리뷰 결정: Comment / Approve / Request changes
  • 병합 방식: merge commit / squash(인기) / rebase
  • 협업자 추가로 직접 기여 권한 부여
  • 보호 브랜치로 PR·승인·CI 통과를 강제 (main 보호)
  • 이슈로 작업 추적, Fixes #번호로 PR과 자동 연결

✍️ 확인 문제

  1. "Pull Request"라는 이름이 붙은 이유는?
  2. 자잘한 커밋을 main에 하나로 깔끔하게 넣는 병합 방식은?
  3. main에 승인 없이는 병합 못 하게 하려면 무엇을 설정하나요?
다음 장에서는 권한이 없는 남의 저장소에 기여하는 방법, 포크(Fork)와 오픈소스 기여를 배웁니다. → 17_포크와오픈소스기여.md