빠른 흐름
# HEAD 이동 기록 보기
git reflog
# 출력 예시
# abc1234 HEAD@{0}: reset: moving to HEAD~2
# def5678 HEAD@{1}: commit: Add login validation
# ghi9012 HEAD@{2}: commit: Init auth module
# 원하는 시점으로 복구
git reset --hard HEAD@{2}
# 또는 dangling commit에서 새 브랜치 생성
git branch recover-login def5678복구 흐름
어떤 복구 흐름을 먼저 떠올리면 되나
| 상황 | 먼저 떠올릴 선택 |
|---|---|
| reset 직전 위치 찾기 | git reflog |
| HEAD 이동 기록 보기 | git reflog |
| 예전 상태로 바로 되돌리기 | git reset --hard HEAD@{n} |
| 사라진 것 같은 커밋을 새 브랜치로 살리기 | git branch recover <hash> |
| 특정 브랜치 이동 기록만 확인 | git reflog show <branch> |
reflog가 기록하는 것은 커밋 히스토리가 아니라 포인터 이동 기록이다
git log는 커밋 객체들의 부모-자식 연결을 따라 히스토리를 보여 준다. git reflog는 다르다. HEAD와 각 브랜치 ref가 어떤 순서로 어느 커밋을 가리켰는지, 즉 포인터 자체의 이동 기록을 보여 준다. reset --hard, rebase, commit --amend, checkout 같은 작업은 모두 ref를 이동시키기 때문에 reflog에 흔적이 남는다. Git 객체 데이터베이스(.git/objects/)에는 한 번 만들어진 커밋 객체가 GC 전까지 남아 있으므로, "사라진 것처럼 보이는 커밋"도 실제로는 존재하는 경우가 많다. reflog가 그 해시를 알려 준다.
reset --hard 후 커밋을 되찾는 흐름 — 가장 자주 쓰이는 복구 패턴이다
git reset --hard HEAD~3처럼 실행하면 브랜치 포인터가 3커밋 뒤로 이동하고 작업 트리도 해당 시점으로 덮어쓴다. 사라진 것처럼 느껴지지만 커밋 객체는 아직 .git/objects/에 남아 있다. git reflog를 실행해 reset 직전에 가리키던 커밋 해시를 찾은 뒤, git reset --hard <hash> 또는 git branch recover-work <hash>로 복구할 수 있다. 실수 직후 바로 실행할수록 reflog 목록에서 해당 항목을 쉽게 찾을 수 있다.
git reset --hard HEAD~2
git reflog
# abc1234 HEAD@{0}: reset: moving to HEAD~2
# def5678 HEAD@{1}: commit: Add login validation
git branch recover-login def5678rebase나 amend 후 원래 커밋을 되찾을 때도 reflog가 핵심 도구다
git rebase는 커밋 객체를 새로 만들고 브랜치 포인터를 새 객체들로 이동시킨다. 원래 커밋들은 어떤 브랜치도 가리키지 않는 "dangling commit"이 되지만 객체 자체는 남는다. git reflog에서 rebase 시작 직전의 해시를 찾으면 원래 커밋 시퀀스 전체를 복구할 수 있다. git commit --amend도 마찬가지다. amend는 새 커밋 객체를 만들고 기존 객체를 버리는 것처럼 보이지만, reflog에 amend 전 해시가 남아 있다. dangling commit을 찾는 또 다른 방법으로 git fsck --lost-found도 활용할 수 있다.
reflog는 로컬 응급 복구 도구다 — 원격 저장소나 다른 사람과 공유되지 않는다
reflog는 내 로컬 저장소 .git/logs/ 디렉터리에 저장되는 로컬 전용 기록이다. git push를 해도 reflog는 원격으로 올라가지 않는다. 또한 Git의 가비지 컬렉션(git gc)이 실행되면 어떤 ref에서도 도달할 수 없는 오래된 커밋 객체는 정리된다. 기본 만료 기간은 90일(unreachable은 30일)이다. 실수 직후 빠르게 확인하는 것이 중요한 이유가 여기 있다. 중요한 커밋은 reflog에 의존하기보다 git tag나 별도 브랜치로 미리 기준점을 남겨 두는 습관이 더 안전하다.
# 내 로컬에서만 보임
git reflog
# 다른 팀원 저장소에서는 같은 reflog를 볼 수 없음체크포인트
| 상황 | 적합한 선택 |
|---|---|
| reset --hard 후 이전 커밋을 되찾고 싶다 | git reflog → git reset --hard HEAD@{n} |
| rebase 전 원래 브랜치 상태를 복구하고 싶다 | git reflog → git branch recover <hash> |
| dangling commit에서 새 브랜치를 만들고 싶다 | git branch <name> <hash> |
| 특정 브랜치의 ref 이동 기록만 보고 싶다 | git reflog show <branch> |
| 복구 가능 기간 | 기본 90일, unreachable 객체는 30일 |
주의할 점
reflog는 만능 백업이 아니라 로컬 이동 기록입니다. 시간이 지나 git gc가 실행되면
오래된 항목은 영구히 삭제될 수 있습니다. 실수 직후 바로 확인하는 것이 가장 효과적이며,
중요한 커밋이라면 reflog 의존보다 git tag나 별도 브랜치로 미리 기준점을 남겨 두는
습관이 더 안전합니다.
참고 링크
1 sources