브랜치 전략 · 충돌 해결 · GitHub Pull Request 리뷰 · Git 심화
독립적인 작업 흐름을 만드는 브랜치, switch/checkout, HEAD 포인터, Fast-forward와 3-way merge의 차이, 그리고 단순한 GitHub Flow 워크플로를 익힙니다. Merge conflict 발생 원리(같은 파일 같은 위치 다른 수정), 충돌 마커 읽기, 5단계 해결 절차, 그리고 rebase와 merge의 차이를 익힙니다. PR의 역할, 좋은 PR 작성 요령(제목·본문 구성), 리뷰 타입(comment/approve/request changes), squash merge vs merge commit, 그리고 PR 템플릿 자동화를 익힙니다. 임시 저장(stash), reset의 3가지 모드, 안전한 revert, 특정 커밋만 가져오는 cherry-pick, 버전 태그, 그리고 잃어버린 커밋을 복구하는 reflog까지.
이 강의에서 배우는 것
- 1브랜치의 개념과 사용 이유를 설명한다
- 2switch -c / branch -d 같은 핵심 명령어를 사용한다
- 3Fast-forward와 3-way merge의 차이를 안다
- 4GitHub Flow의 규칙(main 항상 배포 가능)을 안다
- 5충돌이 나는 조건(같은 파일, 같은 위치, 다른 수정)을 안다
- 6<<<<<<< / ======= / >>>>>>> 마커를 읽는다
- 7충돌 해결 5단계를 따른다
- 8rebase와 merge의 차이와 공유 브랜치 rebase 금지 원칙을 안다
- 9PR의 협업 가치(검증·공유·기록)를 안다
- 10좋은 PR 제목·본문을 작성한다
- 11comment / approve / request changes를 적절히 사용한다
- 12squash merge 와 merge commit을 상황에 맞게 선택한다
- 13PR 템플릿을 만들어 팀 표준을 만든다
- 14stash로 작업을 임시 저장하고 복원한다
- 15reset --soft/--mixed/--hard 의 차이를 안다
- 16공개된 커밋은 reset 대신 revert를 사용한다
- 17cherry-pick으로 특정 커밋만 가져온다
- 18tag로 릴리즈 버전을 표시한다
- 19reflog로 잃어버린 커밋을 복구한다
브랜치 전략
독립적인 작업 흐름을 만드는 브랜치, switch/checkout, HEAD 포인터, Fast-forward와 3-way merge의 차이, 그리고 단순한 GitHub Flow 워크플로를 익힙니다.
1. 브랜치란
main: A --- B --- C
\
feature/login: D --- Efeature/login 에서 D, E를 만들어도 main은 C에 그대로 있습니다.
2. 핵심 명령어
git branch # 현재 브랜치 목록
git branch -a # 원격 포함
git branch feature/login # 새 브랜치 생성
git switch feature/login # 이동 (Git 2.23+)
git switch -c feature/login # 생성 + 이동
# 구버전
git checkout feature/login
git checkout -b feature/login
git branch -d feature/login # 병합된 것만 삭제
git branch -D feature/login # 강제 삭제3. HEAD
cat .git/HEAD
# ref: refs/heads/main
git switch feature/login
cat .git/HEAD
# ref: refs/heads/feature/login4. Fast-forward Merge
병합 전:
main: A --- B
\
feature: C --- D
병합 후 (FF — 단순히 포인터 이동):
main: A --- B --- C --- Dgit switch main
git merge feature/login
git branch -d feature/login5. 3-way Merge
병합 전:
main: A --- B --- C
\
feature: D --- E
병합 후 (병합 커밋 M 생성):
main: A --- B --- C ------- M
\ /
feature: D --- E ---6. Feature 브랜치 워크플로
git switch main
git switch -c feature/login
# 작업 + 커밋
git add login.js
git commit -m "feat: 로그인 기능 추가"
# main에 병합
git switch main
git merge feature/login
git branch -d feature/login7. GitHub Flow
main (항상 배포 가능)
↓ switch -c
feature/기능명
↓ 작업 + 커밋 + push
↓ Pull Request
↓ 코드 리뷰
↓ merge → main
↓ 배포- main은 항상 배포 가능한 상태를 유지
- 새 작업은 무조건 브랜치에서
- 코드 리뷰(PR)를 거쳐야만 main에 병합
git log --oneline --graph --all충돌 해결 (Merge Conflict)
Merge conflict 발생 원리(같은 파일 같은 위치 다른 수정), 충돌 마커 읽기, 5단계 해결 절차, 그리고 rebase와 merge의 차이를 익힙니다.
1. 충돌 발생 원인
공통 조상(A):
button { color: blue; }
main(B): feature(C):
button { color: red; } button { color: green; }
→ Git이 판단 불가 → 충돌!- 다른 파일 수정 → 자동 병합
- 같은 파일, 다른 위치 → 자동 병합
- 같은 파일, 같은 위치 다르게 수정 → 충돌
2. 충돌 마커
<<<<<<< HEAD ← 현재 브랜치 시작
button { color: red; }
======= ← 구분선
button { color: green; }
>>>>>>> feature/login ← 병합하려는 브랜치3. 해결 절차
# 1. 충돌 발생 확인
git merge feature/login
# CONFLICT (content): Merge conflict in style.css
# 2. 어떤 파일이 충돌
git status
# both modified: style.css
# 3. 파일 열어서 마커 제거 + 원하는 내용으로 편집
# 4. 스테이징
git add style.css
# 5. 병합 커밋
git commit
# 중간에 병합을 취소
git merge --abort4. rebase vs merge
merge — 병합 커밋으로
Before: A---B---C (main)
\
D---E (feature)
After (merge):
A---B---C---M (main, M: 병합 커밋)
\ /
D-Erebase — 선형 히스토리
Before: A---B---C (main)
\
D---E (feature)
After (rebase feature onto main):
A---B---C---D'---E' (feature)git switch feature/login
git rebase main # main 위에 feature 커밋들을 재적용
git switch main
git merge feature/login # 이제 Fast-forward!rebase는 혼자 사용하는 로컬 브랜치에만! 팀원과 공유된 브랜치를 rebase하면 다른 팀원의 히스토리가 엉킵니다.
5. 그래프로 시각화
git log --oneline --graph --all
# * abc1234 (HEAD -> main) Merge branch 'feature/login'
# |\
# | * def5678 (feature/login) feat: 로그인 검증 추가
# | * ghi9012 feat: 로그인 페이지 추가
# * | jkl3456 feat: 소개 페이지 추가
# |/
# * mno7890 initGitHub Pull Request 리뷰
PR의 역할, 좋은 PR 작성 요령(제목·본문 구성), 리뷰 타입(comment/approve/request changes), squash merge vs merge commit, 그리고 PR 템플릿 자동화를 익힙니다.
1. PR이란
1. feature 브랜치에서 작업
2. push
3. PR 생성 — "이 변경사항을 main에 병합해주세요"
4. 팀원이 코드 리뷰
5. 승인 후 병합- 코드 품질 검증 (버그 사전 발견)
- 지식 공유 (다른 팀원이 변경사항 파악)
- 히스토리 추적 (왜 이렇게 변경했는지)
2. 좋은 PR 제목
# ✅
feat: 로그인 페이지 UI 구현
fix: 모바일에서 네비게이션 버튼 클릭 안 되는 문제 수정
refactor: UserCard 컴포넌트 단일 책임 원칙 적용
# ❌
수정함
작업완료
fix3. PR 본문 구성
## 변경 내용 (What)
- 로그인 페이지 HTML/CSS 추가
- 이메일 형식 검증 로직 구현
## 변경 이유 (Why)
기존에 로그인 기능이 없어 모든 사용자가 관리자 페이지에 접근 가능
## 스크린샷

## 테스트 방법
1. `npm start`로 앱 실행
2. `/login`으로 이동
3. 잘못된 이메일 형식 입력 시 오류 메시지 확인
## 관련 이슈
Closes #424. 리뷰 타입
| 타입 | 설명 |
|---|---|
| Comment | 일반 의견 — 병합을 막지 않음 |
| Approve | 변경사항 승인 — 병합 가능 |
| Request Changes | 수정 요청 — 해결 전까지 병합 불가 |
좋은 / 나쁜 코멘트
# ✅
"이 함수가 null을 반환할 수 있는데, 호출 지점에서 처리가 없네요.
Optional chaining(user?.name)을 사용하거나 기본값을 지정하면 어떨까요?"
# ❌
"이거 왜 이렇게 했어요?"
"코드 이상함"5. squash merge vs merge commit
merge commit (기본)
main: A --- B --- M
/
feature: C - D - E
squash merge — 모든 커밋이 하나로 합쳐짐
main: A --- B --- Sgit merge --squash feature/login
git commit -m "feat: 로그인 기능 구현 (#PR번호)"- merge commit: 각 커밋이 의미 있고, 기여자별 히스토리 보존이 중요할 때
- squash merge: WIP 커밋이 많아 main 히스토리를 깔끔하게 유지하고 싶을 때
6. PR 템플릿
저장소 루트에 .github/pull_request_template.md 파일이 있으면 PR 생성 시 자동으로 본문에 채워집니다.
## Summary
-
-
## Type of Change
- [ ] 새 기능 (feat)
- [ ] 버그 수정 (fix)
- [ ] 리팩토링 (refactor)
- [ ] 문서 수정 (docs)
## Test
- [ ] 로컬에서 빌드 성공
- [ ] 관련 기능 수동 테스트
## Screenshots
## Related Issue
<!-- Closes #42 -->Git 심화
임시 저장(stash), reset의 3가지 모드, 안전한 revert, 특정 커밋만 가져오는 cherry-pick, 버전 태그, 그리고 잃어버린 커밋을 복구하는 reflog까지.
1. git stash
git stash
git stash push -m "로그인 폼 절반 완성"
git stash list
# stash@{0}: On main: 로그인 폼 절반 완성
git stash pop # 가장 최근 + 목록에서 제거
git stash apply stash@{1} # 특정 stash, 목록 유지
git stash drop stash@{0}
git stash clear2. git reset 3가지 모드
| 옵션 | 커밋 | 스테이징 | 작업 디렉토리 |
|---|---|---|---|
| --soft | 취소 | 유지 | 유지 |
| --mixed | 취소 | 취소 | 유지 |
| --hard | 취소 | 취소 | 취소 |
# 커밋만 취소, 변경은 스테이징 상태로 유지
git reset --soft HEAD~1
# 커밋 취소 + 스테이징 해제 (기본값)
git reset HEAD~1
# 커밋 취소 + 변경 완전 삭제 ⚠️
git reset --hard HEAD~1git reset은 로컬에서만! push된 커밋을 reset하면 팀원의 히스토리와 충돌.
3. git revert — 공개 커밋 안전 되돌리기
git revert abc1234 # 특정 커밋
git revert HEAD # 최근 커밋
git revert HEAD~3..HEAD # 여러 커밋
git revert --no-commit HEAD| reset | revert | |
|---|---|---|
| 동작 | 커밋 삭제 | 되돌리기 커밋 추가 |
| 히스토리 | 변경됨 | 보존됨 |
| 안전성 | 로컬 전용 | push된 커밋도 안전 |
| 팀 작업 | 위험 | 권장 |
4. git cherry-pick
git cherry-pick abc1234 # 특정 커밋
git cherry-pick abc1234 def5678 # 여러 개
git cherry-pick abc1234..def5678 # 범위
# 충돌 해결 후
git add .
git cherry-pick --continue
git cherry-pick --abort예: feature 브랜치의 버그 수정 커밋만 main에 적용.
5. git tag
git tag v1.0.0 # 경량 태그
git tag -a v1.0.0 -m "첫 정식 릴리즈" # 주석 태그 (권장)
git tag -a v0.9.0 abc1234 -m "베타" # 특정 커밋
git tag # 목록
git tag -l "v1.*" # 패턴
git show v1.0.0 # 상세
git push origin v1.0.0 # 태그 push
git push origin --tags # 모든 태그
git tag -d v1.0.0 # 로컬 삭제
git push origin :v1.0.0 # 원격 삭제6. git reflog — 위험한 상황 복구
HEAD가 이동한 모든 이력. reset --hard로 삭제한 커밋도 reflog로 복구 가능!
git reflog
# abc1234 HEAD@{0}: reset: moving to HEAD~3 ← 잘못된 reset!
# def5678 HEAD@{1}: commit: feat: 중요한 기능
git reset --hard HEAD@{1} # 방금 전 상태로
git reset --hard def5678 # 해시로 복구reflog는 로컬에만 — gc 실행 시 사라질 수 있습니다.
댓글 0
아직 댓글이 없습니다. 첫 댓글을 남겨 주세요.
댓글은 회원만 쓸 수 있습니다.
광고·욕설·비방·개인정보·불법 내용이 담긴 댓글은 숨기거나 지웁니다. 댓글은 닉네임과 함께 공개됩니다. 개인정보처리방침