03-05 트러블슈팅과 재해 복구

Git에서 사고가 났을 때 — 잃은 커밋·브랜치 복구, 흔한 실수 대응, 그리고 "거의 모든 건 되돌릴 수 있다".


Git에서 사고가 났을 때 — 잃은 커밋·브랜치 복구, 흔한 실수 대응, 그리고 “거의 모든 건 되돌릴 수 있다”.

목표: 당황하지 않고 올바른 복구 명령을 찾기

[!tip] 첫 번째 진단 사고가 나면 아무것도 하지 말고 먼저 git statusgit 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)reflogreset --hard HEAD@{n}
브랜치 삭제reflogswitch -c <브랜치> <해시>
잘못된 브랜치 커밋cherry-pick + 원본 reset
push 거부pull --rebase → push
비밀키 유출filter-repo + 키 무효화
충돌 꼬임merge/rebase --abort
detached HEADswitch -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