배포 후 장애가 났습니다. 인프라 담당이 묻습니다. "이번 배포에 뭐가 들어갔죠?" 개발자가 "main에 머지된 PR 다섯 개요"라고 답합니다. PM은 "어제 그 기능 롤백되면 다른 작업도 사라지나요?"가 궁금합니다. 커밋·브랜치·머지·PR이라는 단어의 의미와 관계를 모르면, 이 대화에서 아무 판단도 내릴 수 없습니다. Git은 개발자만의 도구가 아니라, 변경을 추적하는 팀 전체의 기록 시스템입니다.
- 1커밋이 "변경의 스냅샷이자 추적 단위"임을 설명할 수 있다
- 2브랜치가 "독립 작업 공간"이고 머지로 합쳐짐을 설명할 수 있다
- 3머지 충돌이 왜 생기고 왜 정상인지 설명할 수 있다
- 4git log/blame으로 장애·릴리스 범위를 조사할 수 있다
Git이 추적하는 것 — 변경의 역사
커밋: 누가·언제·왜 바꿨는가의 스냅샷
Git은 파일의 변경 이력을 추적하는 시스템입니다. 핵심 단위가 커밋입니다.
커밋 = 변경 스냅샷 + 메시지 + 작성자 + 시각 + 고유 해시
a3f4b1c feat: 결제 카드 연동 추가 (홍길동, 2시간 전)
9f8e7d6 fix: 중복 결제 방지 (김철수, 어제)
2c1b0a9 docs: API 문서 업데이트 (이영희, 2일 전)
각 커밋은 고유 해시(a3f4b1c)로 식별되며, 이력이 사슬처럼 이어집니다. 그래서:
- 되돌리기: 문제가 된 커밋만 되돌릴 수 있다(revert).
- 추적: "이 줄을 누가 언제 왜 바꿨나"를 blame으로 확인.
- 릴리스 범위: "이번 배포 = 이 커밋부터 저 커밋까지"로 정의.
커밋은 배포가 아닙니다 — 기록입니다. 배포는 그 기록 중 특정 시점을 프로덕션에 반영하는 별개 행위입니다([[cicd-pipeline]]).
브랜치와 머지 — 평행 작업과 합치기
브랜치: 메인을 지키며 따로 일하는 공간
여러 명이 한 코드베이스에서 동시에 일하려면, 서로의 미완성 작업이 섞이면 안 됩니다. 브랜치가 이를 해결합니다.
main ●───●───●───────────● (항상 동작하는 안정 코드)
\ / merge
feature/pay ●───●───●───● (결제 기능 — 독립 작업)
1. main에서 feature 브랜치를 딴다
2. 거기서 자유롭게 커밋(메인 영향 없음)
3. 완성되면 PR(Pull Request)로 리뷰 후 main에 머지
- 브랜치: 독립된 평행 작업선. 망쳐도 main은 안전.
- 머지(merge): 브랜치의 변경을 main에 합치는 것.
- PR(Pull Request): "내 브랜치를 main에 합쳐 주세요" 요청 + 리뷰·테스트 게이트([[code-review-pr]]).
PM 관점: "그 기능 롤백하면 다른 작업도 사라지나요?" → 브랜치/커밋이 분리돼 있으면 그 PR의 커밋만 되돌리면 됩니다. 이것이 브랜치 전략([[branch-strategy]])이 중요한 이유입니다.
히스토리로 장애 조사하기 — 직접 해보기
코드를 못 짜도 Git 히스토리는 강력한 조사 도구입니다. 두 릴리스 사이의 변경, 특정 줄의 변경자를 확인합니다.
# 이전 릴리스(v1.1.0)부터 현재(v1.2.0)까지 들어간 커밋 = 이번 배포 범위
git log --oneline v1.1.0..v1.2.0
# 특정 파일의 특정 줄을 누가 언제 바꿨나 (장애 의심 코드 추적)
git blame -L 40,50 payment/service.js
# 어제 이후 결제 관련 변경만
git log --since="yesterday" --oneline -- payment/
$ git log --oneline v1.1.0..v1.2.0
a3f4b1c feat: 결제 카드 연동 추가 ← 장애 시각과 겹침? 1순위 의심
9f8e7d6 fix: 중복 결제 방지
2c1b0a9 chore: 의존성 업데이트
→ 이번 배포에 3개 커밋. 장애가 결제 쪽이면 a3f4b1c부터 본다
git log --oneline v1.1.0..v1.2.0- v1.1.0..v1.2.0 범위의 커밋 목록이 곧 "이번 배포에 들어간 변경" — 장애 영역과 겹치는 커밋부터 의심한다. 목록이 비면 잘못된 태그 범위
- git blame으로 의심 줄의 변경 커밋·작성자를 보고 → 그 커밋 메시지/PR에서 "왜 이렇게 바꿨나" 맥락을 찾는다(작성자에게 직접 물을 근거)
- 한 커밋에 수십 개 파일이 섞여 있으면(거대 커밋) 추적이 어렵다 → 팀에 "작은 커밋·작은 PR"을 요청하는 근거
- 롤백 결정 시 git revert <커밋>은 해당 변경만 되돌린다 — 다른 작업은 보존. "다 사라지나요?"의 답은 보통 No(분리돼 있으면)
상황: 장애 후 "방금 배포한 결제 변경만 되돌려 주세요"라고 요청했지만, 개발자가 "그 커밋에 결제·알림·리팩터링이 다 섞여 있어 결제만 되돌리면 다른 것도 깨져요"라고 답합니다.
원인: 하나의 커밋/PR에 여러 관심사가 뭉쳐 있습니다. Git의 되돌리기는 커밋 단위라, 한 커밋에 여러 변경이 섞이면 선택적 롤백이 어렵습니다. 이는 코드 문제가 아니라 '변경을 작게 나누지 않은' 협업 습관의 문제입니다.
진단:
git show --stat <커밋> # 이 커밋이 건드린 파일 범위 확인
# 결제·알림·설정이 한 커밋에 다 있으면 = 뭉친 커밋
해결: 단기적으론 전체 배포를 이전 태그로 롤백(git checkout v1.1.0 기반 재배포)하고 결제만 다시 분리 작업합니다. 근본적으론 팀에 "한 PR = 한 관심사" 원칙을 요청합니다([[code-review-pr]]). 작은 커밋·작은 PR은 리뷰 품질뿐 아니라 장애 시 선택적 롤백을 가능하게 하는 운영 안전장치입니다 — 인프라/SRE가 강하게 요구할 명분이 있습니다.
인프라/SRE로서 장애 대응의 첫 5분은 종종 Git 히스토리에서 시작합니다 — "이번 배포에 뭐가 들어갔지?"를 git log <이전태그>..<현재태그>로 좁히고, 의심 커밋의 PR에서 변경 의도를 읽습니다. 또한 "작은 PR·의미 있는 커밋 메시지"를 팀에 요구하는 것은 잔소리가 아니라, 선택적 롤백과 빠른 원인 추적을 가능하게 하는 운영 요구입니다. PM은 Git 히스토리로 릴리스 노트를 자동 생성하고(커밋→변경 목록), 기능의 진행을 PR 상태로 추적합니다. Git은 개발자만의 것이 아니라, 변경을 다루는 모든 역할의 공용 기록입니다.
다음 모듈에서는 이 브랜치들을 팀이 어떤 규칙으로 운영하는가 — Git Flow와 Trunk-based 같은 브랜치 전략을 다룹니다.