03-05 트러블슈팅과 재해 복구
Git에서 사고가 났을 때 — 잃은 커밋·브랜치 복구, 흔한 실수 대응, 그리고 "거의 모든 건 되돌릴 수 있다".
Git에서 사고가 났을 때 — 잃은 커밋·브랜치 복구, 흔한 실수 대응, 그리고 “거의 모든 건 되돌릴 수 있다”.
목표: 당황하지 않고 올바른 복구 명령을 찾기
[!tip] 첫 번째 진단 사고가 나면 아무것도 하지 말고 먼저
git status와git reflog를 본다. 추가 작업이 상황을 더 꼬이게 할 수 있다.
🦸 복구의 핵심: reflog & fsck
git reflog # HEAD가 거쳐온 모든 위치(잃은 커밋 단서) ⭐
git reflog show <branch> # 특정 브랜치 이동 기록
git fsck --lost-found # 어디서도 참조 안 되는 dangling 객체
Git은 보통 즉시 삭제하지 않는다(기본 90일 reflog 보관, gc 전까지 객체 유지). 대부분의 “잃었다”는 복구 가능하다.
🔧 상황별 대응
1. 잘못된 브랜치에 커밋했다
git switch 올바른브랜치
git cherry-pick <커밋해시> # 올바른 곳으로 복사
git switch 원래브랜치
git reset --hard HEAD~1 # 원래 브랜치에서 제거(로컬만일 때)
2. reset --hard로 커밋을 날렸다
git reflog # 날리기 직전 해시 찾기
git reset --hard HEAD@{1} # 그 시점으로 복구
3. 브랜치를 실수로 삭제했다
git reflog # 삭제된 브랜치의 마지막 커밋 찾기
git switch -c 되살린브랜치 <해시>
4. push가 거부된다 (non-fast-forward)
git pull --rebase # 원격 위로 재배치
git push
5. 강제 push로 동료 커밋을 날렸다
# 동료가 자기 로컬에서:
git reflog
git reset --hard HEAD@{1}
# 예방: 항상 --force-with-lease 사용
6. 커밋 작성자/이메일이 잘못 찍혔다
git commit --amend --author="Name <email>" --no-edit # 마지막 커밋
# 여러 커밋이면 rebase -i + 또는 filter-repo
7. 큰 파일/비밀키를 커밋·push했다
git filter-repo --invert-paths --path secrets.env # 히스토리에서 제거
git push --force-with-lease --all
# ⚠️ 유출된 비밀은 반드시 무효화(rotate)! → 03-03 참고
8. 충돌이 꼬여 손쓸 수 없다
git merge --abort # 또는 git rebase --abort
9. detached HEAD 상태가 됐다
git switch -c temp # 현재 위치를 브랜치로 저장
# 또는 그냥 git switch main 으로 복귀(커밋 안 했다면)
10. 방금 변경을 전부 날리고 원격과 동일하게
git fetch origin
git reset --hard origin/main # 🔴 로컬 변경 전부 삭제
git clean -fd # untracked까지 제거
🗂️ 빠른 참조표
| 증상 | 해결 |
|---|---|
커밋 날림(reset --hard) | reflog → reset --hard HEAD@{n} |
| 브랜치 삭제 | reflog → switch -c <브랜치> <해시> |
| 잘못된 브랜치 커밋 | cherry-pick + 원본 reset |
| push 거부 | pull --rebase → push |
| 비밀키 유출 | filter-repo + 키 무효화 |
| 충돌 꼬임 | merge/rebase --abort |
| detached HEAD | switch -c temp |
| 메시지 오타(push 전) | commit --amend |
| 메시지 오타(push 후) | revert 또는 알림 후 강제 정리 |
🛡️ 사고 예방 습관
- 위험 작업 전 백업 브랜치:
git branch backup/$(date +%s) - 강제 push는 항상
--force-with-lease - 공유 브랜치는
revert(reset 금지) - 자주 push해서 로컬에만 있는 작업을 최소화
- 비밀은 처음부터
.gitignore+ 시크릿 매니저
📋 체크리스트
- 사고 시 reflog/fsck 우선 확인
- reset —hard 후 reflog 복구
- 삭제 브랜치 복구
- 잘못된 브랜치 커밋 이동
- non-ff push 대응
- 비밀 유출 시 제거 + 무효화
- detached HEAD 탈출
- 예방 습관 체득
🔗 관련 노트
- 03-04-Git-훅과-자동화 — 이전
- 00-MOC-Git — 시리즈 지도
- 01-05-되돌리기와-복구 — 되돌리기 기초
- 03-01-Git-내부-객체-모델 — fsck·dangling 이해
- 03-03-모노레포와-대용량-관리 — filter-repo
마지막 업데이트: 2026-06-02