← 홈페이지 5강 목록으로
📝
EPISODE 03
PR · 리뷰 · squash merge · PR 템플릿

GitHub Pull Request 리뷰

PR의 역할, 좋은 PR 작성 요령(제목·본문 구성), 리뷰 타입(comment/approve/request changes), squash merge vs merge commit, 그리고 PR 템플릿 자동화를 익힙니다.

GitHubPull Requestcode review
소요 시간
45분
난이도
📊 중급
선수 조건
🎯 git-coop-02
결과물
팀에서 통할 수 있는 깔끔한 PR 작성과 리뷰

이 강의에서 배우는 것

  • 1PR의 협업 가치(검증·공유·기록)를 안다
  • 2좋은 PR 제목·본문을 작성한다
  • 3comment / approve / request changes를 적절히 사용한다
  • 4squash merge 와 merge commit을 상황에 맞게 선택한다
  • 5PR 템플릿을 만들어 팀 표준을 만든다

1. PR이란

text
1. feature 브랜치에서 작업
2. push
3. PR 생성 — "이 변경사항을 main에 병합해주세요"
4. 팀원이 코드 리뷰
5. 승인 후 병합
  • 코드 품질 검증 (버그 사전 발견)
  • 지식 공유 (다른 팀원이 변경사항 파악)
  • 히스토리 추적 (왜 이렇게 변경했는지)

2. 좋은 PR 제목

text
# ✅
feat: 로그인 페이지 UI 구현
fix: 모바일에서 네비게이션 버튼 클릭 안 되는 문제 수정
refactor: UserCard 컴포넌트 단일 책임 원칙 적용

# ❌
수정함
작업완료
fix

3. PR 본문 구성

markdown
## 변경 내용 (What)
- 로그인 페이지 HTML/CSS 추가
- 이메일 형식 검증 로직 구현

## 변경 이유 (Why)
기존에 로그인 기능이 없어 모든 사용자가 관리자 페이지에 접근 가능

## 스크린샷
![로그인 페이지](screenshot.png)

## 테스트 방법
1. `npm start`로 앱 실행
2. `/login`으로 이동
3. 잘못된 이메일 형식 입력 시 오류 메시지 확인

## 관련 이슈
Closes #42

4. 리뷰 타입

타입설명
Comment일반 의견 — 병합을 막지 않음
Approve변경사항 승인 — 병합 가능
Request Changes수정 요청 — 해결 전까지 병합 불가

좋은 / 나쁜 코멘트

text
# ✅
"이 함수가 null을 반환할 수 있는데, 호출 지점에서 처리가 없네요.
Optional chaining(user?.name)을 사용하거나 기본값을 지정하면 어떨까요?"

# ❌
"이거 왜 이렇게 했어요?"
"코드 이상함"

5. squash merge vs merge commit

text
merge commit (기본)
main: A --- B --- M
                /
feature: C - D - E

squash merge — 모든 커밋이 하나로 합쳐짐
main: A --- B --- S
bash
git merge --squash feature/login
git commit -m "feat: 로그인 기능 구현 (#PR번호)"
  • merge commit: 각 커밋이 의미 있고, 기여자별 히스토리 보존이 중요할 때
  • squash merge: WIP 커밋이 많아 main 히스토리를 깔끔하게 유지하고 싶을 때

6. PR 템플릿

저장소 루트에 .github/pull_request_template.md 파일이 있으면 PR 생성 시 자동으로 본문에 채워집니다.

markdown
## Summary
-
-

## Type of Change
- [ ] 새 기능 (feat)
- [ ] 버그 수정 (fix)
- [ ] 리팩토링 (refactor)
- [ ] 문서 수정 (docs)

## Test
- [ ] 로컬에서 빌드 성공
- [ ] 관련 기능 수동 테스트

## Screenshots

## Related Issue
<!-- Closes #42 -->
예제 코드 / 강의 자료

전체 강의 자료와 예제 코드는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗