Quick Flow
# 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는 내 local repository .git/logs/에 저장되는 local-only 기록입니다. git push해도 reflog 자체는 remote로 올라가지 않습니다. reflog expiry와 unreachable object pruning은 Git configuration·maintenance/GC policy에 따라 달라지므로 정해진 보존 일수를 복구 약속으로 쓰면 안 됩니다. 중요한 commit은 reflog에 의존하기보다 branch/tag를 붙이고 필요한 remote에 push합니다.
# 내 로컬에서만 보임
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> |
| 보존 기간 확인 | git config --show-origin --get-regexp '^gc\.reflogExpire' |
주의할 점
reflog는 만능 백업이 아니라 로컬 이동 기록입니다. 시간이 지나 git gc가 실행되면
오래된 항목은 영구히 삭제될 수 있습니다. 실수 직후 바로 확인하는 것이 가장 효과적이며,
중요한 커밋이라면 reflog 의존보다 git tag나 별도 브랜치로 미리 기준점을 남겨 두는
습관이 더 안전합니다.
참고 링크
1 sources