GitHub Pull Request 리뷰와 머지 방법: 실무 워크플로 완전 가이드

여러 개발자가 하나의 프로젝트에서 협업할 때 작성한 코드를 곧바로 main 브랜치에 반영하면 검토되지 않은 오류가 제품에 들어가기 쉽습니다. 일반적인 팀은 별도 브랜치에서 작업한 뒤 Pull Request(PR)를 만들고, 사람의 리뷰와 자동 검사를 모두 통과한 변경만 기본 브랜치에 반영합니다.

가장 실용적인 기본 흐름은 다음과 같습니다.

기능 브랜치 생성 → Draft PR → 자동 검사 → 코드 리뷰 → 수정과 승인 → Squash and merge → 작업 브랜치 삭제

이 글은 GitHub 웹, VS Code, GitHub CLI, GitHub Actions를 어떻게 조합하는지와 세 가지 머지 방식, Ruleset·브랜치 보호·CODEOWNERS까지 한 번에 정리합니다. 2026년 8월 7일 기준 GitHub 공식 문서와 공식 도구 문서를 확인해 작성했습니다.

Pull Request란?

Pull Request는 한 브랜치의 변경을 다른 브랜치에 반영해 달라고 제안하는 GitHub의 협업 단위입니다. 단순한 “합치기 버튼”이 아니라 다음 정보를 한곳에서 관리합니다.

  • 변경 목적과 관련 이슈
  • 수정된 파일과 커밋
  • 코드 라인별 의견과 전체 리뷰
  • 자동 테스트·빌드·보안 검사 결과
  • 승인과 머지 기록

로그인 화면을 만든다면 먼저 기능 브랜치를 생성합니다.

git switch -c feature/login-page

변경 범위만 선택해 커밋하고 원격 브랜치로 올립니다.

git add src/login
git commit -m "feat: add login page"
git push -u origin feature/login-page

이제 feature/login-pagemain에 합치기 위한 PR을 만들면, 기본 브랜치를 건드리지 않은 상태에서 팀이 변경을 검토할 수 있습니다.

리뷰하기 쉬운 PR 작성법

좋은 PR은 리뷰어가 세 가지 질문에 빠르게 답할 수 있게 합니다.

  1. 왜 바꾸었는가?
  2. 무엇이 바뀌었는가?
  3. 어떻게 검증하는가?

제목은 결과를 짧고 구체적으로 적습니다.

feat: add login page

본문은 다음 정도면 충분합니다.

## 작업 내용

- 로그인 폼과 유효성 검사 추가
- 성공·실패 상태 처리

## 테스트 방법

1. 이메일과 비밀번호를 입력합니다.
2. 로그인 버튼을 누릅니다.
3. 성공·실패 메시지와 모바일 화면을 확인합니다.

## 리뷰 요청 사항

- 실패 시 오류 처리 방식이 적절한지 확인해 주세요.
- 키보드만으로 폼을 사용할 수 있는지 확인해 주세요.

기능 추가, 대규모 리팩터링, 스타일 정리를 한 PR에 섞지 마세요. GitHub도 작고 초점이 분명한 PR이 더 빠르고 안전하게 리뷰된다고 안내합니다.

Draft Pull Request를 먼저 만드는 이유

작업이 끝나기 전이라도 Draft PR을 만들 수 있습니다. 구현 방향을 조기에 공유하고 CI를 미리 실행하며, 다른 팀원의 중복 작업도 줄일 수 있습니다.

Draft PR은 머지할 수 없고 CODEOWNERS에게 정식 리뷰가 자동 요청되지 않습니다. 작업이 끝난 뒤 Ready for review로 바꾸면 코드 소유자에게 리뷰 요청이 전달됩니다. 따라서 규모가 큰 기능은 다음처럼 운영하기 좋습니다.

  1. 기본 구조가 잡히면 Draft PR을 만듭니다.
  2. 설명에 남은 작업과 결정이 필요한 부분을 적습니다.
  3. 자동 검사를 고치고 방향성 피드백을 반영합니다.
  4. 준비가 끝나면 Ready for review로 전환합니다.

GitHub 웹에서 리뷰하는 순서

PR 화면은 주로 다음 영역으로 구성됩니다.

영역확인할 내용
Conversation목적, 관련 이슈, 전체 논의, 승인과 머지 상태
Commits작업 브랜치에 포함된 커밋과 변화 과정
ChecksCI, 테스트, 빌드, 보안 검사 결과
Files changed실제 diff와 코드 라인별 리뷰
Findings저장소 설정에 따라 표시되는 코드 스캔 등 자동 분석 결과

먼저 Conversation에서 요구사항과 테스트 방법을 읽고, Checks의 실패 여부를 확인한 뒤 Files changed로 이동합니다. 코드가 정상처럼 보여도 요구사항과 다른 기능이라면 올바른 변경이 아닙니다.

Files changed에서 볼 것

모든 PR에 같은 체크리스트를 기계적으로 적용하기보다 변경 위험도에 맞춰 봅니다.

  • 기능: 정상 흐름, 오류·빈 상태, 기존 기능 회귀
  • 코드: 명확한 이름, 책임 분리, 중복과 불필요한 복잡성
  • 테스트: 핵심 로직, 실패 조건, 회귀 테스트
  • 보안: 입력 검증, 권한 검사, 비밀 값 노출, 안전하지 않은 HTML
  • 프런트엔드: 반응형, 로딩, 키보드 접근성, 렌더링과 번들 영향

파일을 확인했다면 Viewed로 표시해 진행률을 관리할 수 있습니다. 큰 PR일수록 파일 단위로 확인하는 편이 누락을 줄입니다.

Comment, Approve, Request changes의 차이

GitHub의 리뷰 결정은 세 가지입니다.

Comment

질문이나 선택적 제안을 남기지만 승인 또는 변경 요청 상태를 만들지는 않습니다. 보통 머지를 차단하지 않습니다.

질문: 이 로직을 공통 유틸리티로 분리하지 않은 이유가 있을까요?

Approve

현재 변경이 머지 가능한 수준이라고 판단했음을 표시합니다. 승인 전에 주요 변경, CI, 미해결 대화, 필요한 로컬 테스트와 보안 위험을 확인합니다.

Request changes

머지 전 반드시 해결해야 할 문제를 표시합니다. 예를 들면 기능 오류, 데이터 손실 가능성, 보안 취약점, 실패한 테스트, 요구사항 누락입니다.

중요한 주의점이 있습니다. Request changes 자체가 언제나 머지를 막는 것은 아닙니다. 실제 차단 조건으로 사용하려면 Ruleset 또는 브랜치 보호에서 PR 리뷰를 필수로 설정해야 합니다.

좋은 리뷰 댓글의 구조

사람을 평가하지 말고 코드와 영향을 설명합니다. 다음 네 요소를 포함하면 대화가 짧아집니다.

  1. 어떤 문제가 있는가
  2. 왜 문제가 되는가
  3. 언제 재현되는가
  4. 가능한 해결 방향은 무엇인가
필수: API 요청이 실패하면 로딩 상태가 해제되지 않습니다.
사용자는 화면이 멈춘 것으로 인식할 수 있으므로 finally에서 로딩 상태를 정리하거나
실패 분기에서 명시적으로 상태를 갱신해 주세요.

의견의 성격도 표시해 보세요.

  • 필수: 머지 전 수정 필요
  • 제안: 선택적 개선
  • 질문: 의도 확인
  • 사소함: 동작에 영향 없는 작은 정리

구체적인 한두 줄 수정은 GitHub의 Suggestion으로 제안할 수 있습니다. 여러 제안을 묶어서 하나의 커밋으로 적용할 수도 있습니다. 범위가 큰 수정은 작성자가 로컬에서 맥락과 테스트를 함께 반영하는 편이 안전합니다.

언제 로컬에서 실행해야 할까?

오타나 문구 수정은 웹 diff만으로 충분할 수 있습니다. 다음 변경은 직접 체크아웃해 실행하는 편이 좋습니다.

  • 핵심 비즈니스 로직과 데이터 처리
  • UI 레이아웃, 반응형, 애니메이션
  • 폼 검증, API 성공·실패 흐름
  • 키보드 접근성과 브라우저 호환성
  • 빌드 설정과 패키지 업데이트

GitHub CLI를 사용하면 PR을 바로 가져올 수 있습니다.

gh pr checkout 123
npm ci
npm run lint
npm run type-check
npm test
npm run build

프로젝트에 존재하는 스크립트만 실행하고, UI 변경은 개발 서버에서 핵심 화면 크기와 상호작용을 확인합니다.

VS Code와 GitHub CLI 활용법

VS Code 사용자는 GitHub Pull Requests 확장으로 PR 체크아웃, diff 확인, 라인 댓글, 리뷰 제출과 로컬 실행을 한 화면에서 처리할 수 있습니다. 정의와 타입을 따라가며 실제 코드 문맥을 볼 수 있다는 것이 웹 리뷰보다 좋은 점입니다.

터미널 중심이라면 다음 gh 명령만 익혀도 대부분의 작업을 처리합니다.

# 목록과 상세 정보
gh pr list
gh pr view 123
gh pr view 123 --web

# diff, 체크아웃, CI
gh pr diff 123
gh pr checkout 123
gh pr checks 123 --watch

# 리뷰
gh pr review 123 --approve
gh pr review 123 --comment --body "오류 처리 방식을 확인해 주세요."
gh pr review 123 --request-changes --body "실패 시 로딩 상태가 종료되지 않습니다."

# 조건 충족 후 squash merge와 브랜치 삭제
gh pr merge 123 --squash --delete-branch

# 조건이 충족되면 자동 머지
gh pr merge 123 --squash --auto

라인별 댓글이 많다면 GitHub 웹이나 VS Code가 편하고, 상태 확인과 반복 작업은 CLI가 빠릅니다. 실제 머지 명령은 저장소 권한과 팀 규칙을 확인한 뒤 실행해야 합니다.

GitHub Actions로 자동 검사 만들기

문법, 포맷, 타입, 테스트, 빌드처럼 기계가 반복해서 판단할 수 있는 일은 CI에 맡깁니다. 다음은 2026년 8월 기준 공식 액션의 현재 메이저 버전을 사용한 Node.js 예시입니다.

name: Pull Request Check

on:
  pull_request:
    branches: [main]

permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Set up Node.js
        uses: actions/setup-node@v6
        with:
          node-version: 24
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Run lint
        run: npm run lint

      - name: Run type check
        run: npm run type-check

      - name: Run tests
        run: npm test

      - name: Run build
        run: npm run build

프로젝트에 없는 명령은 제거하거나 실제 스크립트 이름으로 바꿉니다. 보안 요구가 높은 저장소는 액션 태그 대신 검증된 전체 커밋 SHA로 고정하는 것이 가장 안전합니다. GitHub도 전체 SHA가 변경 불가능한 액션 릴리스를 참조하는 유일한 방법이라고 안내합니다.

자동 검사가 대신할 수 없는 판단도 있습니다.

  • 요구사항과 구현 방향
  • 시스템 설계와 유지보수성
  • 사용자 경험과 접근성
  • 장기적인 변경 영향

CI는 사람 리뷰를 대체하는 것이 아니라 사람이 더 중요한 판단에 집중하도록 돕습니다.

세 가지 머지 방식 비교

GitHub 저장소는 허용할 머지 방식을 설정할 수 있습니다.

방식개별 커밋 보존별도 merge commit적합한 환경
Squash and merge아니요아니요일반적인 제품·웹 개발
Create a merge commit브랜치 구조와 모든 커밋을 보존할 때
Rebase and merge아니요의미 있는 커밋으로 선형 이력을 유지할 때

Squash and merge

PR의 여러 커밋을 하나로 합쳐 기본 브랜치에 반영합니다. 작업 중 만든 fix, wip 커밋이 남지 않고 PR 하나와 커밋 하나가 대응해 추적과 되돌리기가 쉽습니다. 대신 개별 커밋의 작성 시점과 맥락은 기본 브랜치에서 사라집니다.

대부분의 웹 제품 팀에는 가장 무난한 기본값입니다.

Create a merge commit

모든 커밋을 보존하고 병합 커밋을 추가합니다. 장기간 유지되는 브랜치나 브랜치 구조 자체가 중요한 환경에 유용하지만, 작은 PR이 많으면 그래프가 복잡해집니다.

Rebase and merge

각 커밋을 기본 브랜치 최신 지점 뒤에 다시 적용해 선형 이력을 만듭니다. 커밋이 작고 독립적으로 잘 정리된 팀에 적합합니다. GitHub에서 rebase merge를 하면 새 커밋 SHA가 만들어진다는 점도 기억해야 합니다.

Auto-merge와 Merge queue

Auto-merge

저장소에서 Auto-merge를 허용하면, 필수 승인과 상태 검사가 모두 통과했을 때 PR을 자동으로 머지할 수 있습니다. CI가 오래 걸리거나 작은 PR이 자주 들어오는 팀에 편리합니다.

단, 배포 일정이나 운영 승인처럼 자동으로 표현할 수 없는 조건이 있다면 바로 사용하지 마세요. 저장소에서 먼저 Auto-merge를 허용해야 하며, GitHub 웹의 옵션은 아직 머지 조건을 충족하지 못한 PR에서만 보일 수 있습니다.

Merge queue

여러 PR이 빠르게 main에 들어가는 저장소에서는 각 PR이 혼자 CI를 통과해도 연속 머지 후 조합이 깨질 수 있습니다. Merge queue는 최신 기본 브랜치와 앞선 PR을 합친 임시 상태에서 다시 검사하고 순서대로 머지합니다.

GitHub Actions를 사용한다면 워크플로가 큐 검사를 실행하도록 이벤트를 추가해야 합니다.

on:
  pull_request:
  merge_group:

Merge queue는 모든 저장소에 동일하게 제공되지 않습니다. 현재 공식 기준으로 조직 소유 공개 저장소 또는 GitHub Enterprise Cloud 조직의 비공개 저장소에서 사용할 수 있으므로 요금제와 소유 형태를 확인하세요.

충돌을 안전하게 해결하기

기본 브랜치의 최신 내용을 가져온 뒤 작업 브랜치에 merge하거나 rebase합니다.

git fetch origin
git switch feature/login-page

# 팀이 merge 방식을 쓰는 경우
git merge origin/main

rebase를 선택했다면 충돌을 해결하고 다음처럼 진행합니다.

git rebase origin/main
git add src/login/LoginForm.tsx
git rebase --continue
git push --force-with-lease

공유 브랜치에서 rebase하면 이력이 바뀝니다. 팀원과 합의하고 일반 --force 대신 --force-with-lease를 사용해야 다른 사람이 올린 커밋을 덮어쓸 위험을 줄일 수 있습니다. 충돌 해결 후 테스트와 빌드는 다시 실행합니다.

Ruleset과 브랜치 보호 설정

PR 프로세스를 개인의 주의력에만 맡기지 말고 저장소 규칙으로 강제합니다. GitHub는 전통적인 Branch protection rule과 더 유연하게 여러 규칙을 함께 적용할 수 있는 Ruleset을 제공합니다.

대부분의 팀은 main에 다음 조건부터 적용하면 됩니다.

  • PR을 통해서만 변경
  • 최소 1명 승인
  • 필수 CI 상태 검사 통과
  • 리뷰 대화 해결 필수
  • Force push와 브랜치 삭제 제한
  • 필요하면 최신 기본 브랜치 반영 또는 Merge queue 사용

위험도가 높은 프로젝트라면 CODEOWNERS 승인, 새 커밋 시 기존 승인 무효화, 최근 푸시에 대한 타인 승인, 코드 스캔·배포 성공, 규칙 우회 제한도 검토합니다.

필수 상태 검사의 job 이름은 워크플로마다 고유하게 만드세요. 같은 이름이 여러 워크플로에 있으면 결과가 모호해져 머지가 막힐 수 있습니다.

CODEOWNERS로 리뷰 자동 배정하기

CODEOWNERS 파일에 경로별 담당자를 지정하면 해당 파일이 변경된 PR에서 리뷰어가 자동 요청됩니다.

/src/components/  @frontend-team
/src/api/         @backend-team
/.github/         @devops-team
/docs/            @documentation-team

Draft PR에서는 자동 요청되지 않고 Ready for review로 바뀔 때 요청됩니다. 담당자가 불명확한 대규모 저장소, 보안·인프라·공통 라이브러리처럼 전문 검토가 필요한 영역에서 특히 유용합니다.

보안·품질 도구는 언제 추가할까?

  • CodeQL: 데이터 흐름과 취약 패턴을 분석하고 PR에 코드 스캔 결과를 표시
  • Dependabot: 의존성 업데이트와 보안 업데이트 PR 생성
  • SonarQube·SonarCloud: 버그, 중복, 복잡도, 커버리지 기반 Quality Gate
  • Copilot code review: 사람 리뷰 전에 일반적인 오류와 개선 후보를 제안

AI 리뷰는 보조 검사입니다. 프로젝트 요구사항과 조직의 설계 원칙, 비즈니스 맥락을 놓칠 수 있으므로 최종 승인 책임은 사람에게 둡니다. 또한 도구가 많을수록 좋은 것이 아니라, 도입 비용보다 해결하는 문제가 분명할 때 추가해야 합니다.

가장 추천하는 실무 워크플로

  1. 최신 main에서 기능 브랜치를 만듭니다.
  2. 변경 범위를 작게 유지하고 의미 있는 단위로 커밋합니다.
  3. 초기부터 Draft PR로 목적과 진행 상황을 공유합니다.
  4. CI가 lint, type check, test, build를 실행합니다.
  5. 완료 후 Ready for review로 바꾸고 적절한 리뷰어를 지정합니다.
  6. 리뷰어는 목적 → Checks → Files changed → 필요 시 로컬 실행 순서로 확인합니다.
  7. 작성자는 피드백을 반영하고 대화를 해결한 뒤 재리뷰를 요청합니다.
  8. 승인과 필수 검사가 모두 통과하면 Squash and merge합니다.
  9. 작업 브랜치를 삭제하고, 후속 제안은 별도 이슈로 분리합니다.

규모별로는 다음 정도가 현실적입니다.

환경권장 구성
개인·소규모GitHub 웹 + Actions + Squash merge
일반 제품팀Actions + Ruleset/보호 규칙 + CODEOWNERS + Auto-merge
터미널 중심 팀GitHub CLI + Actions + Squash merge
PR이 매우 많은 조직위 구성 + Merge queue
보안 요구가 높은 서비스CodeQL/의존성 리뷰 + CODEOWNERS + 엄격한 규칙

결론

Pull Request의 가치는 코드를 합치는 데 있지 않습니다. 변경 목적을 공유하고, 자동화가 반복 가능한 오류를 검사하며, 사람이 설계·가독성·사용자 경험과 장기 영향을 판단하도록 만드는 데 있습니다.

처음부터 복잡하게 시작할 필요는 없습니다.

작은 PR → CI 검사 → 사람 리뷰와 승인 → Squash and merge

이 네 단계를 안정적으로 운영한 다음 CODEOWNERS, Auto-merge, 정적 분석, Merge queue를 팀의 문제에 맞춰 추가하세요. 도구의 수보다 중요한 것은 머지 조건이 명확하고, 누가 최종 책임을 지는지 팀 모두가 이해하는 것입니다.

공식 자료