23장에서 git reset --hard를 다루며 “되돌려진 커밋은 즉시 사라지는 것이 아니라 얼마간 복구할 여지가 남는다"고 언급했다. git reflog가 바로 그 복구를 가능하게 하는 안전망이다. 이 장은 5부를 마무리하며, 실수로 브랜치를 잘못 되돌리거나 삭제했을 때 가장 먼저 확인해야 할 이 명령을 다룬다.
개요
| |
| |
이 목록은 09장에서 다룬 git log와 근본적으로 다른 것을 보여준다 — git log가 커밋 그래프(부모 관계)를 따라가는 히스토리라면, reflog는 이 컴퓨터에서 HEAD가 실제로 어떤 순서로 어디를 가리켰는지의 이동 기록이다. 위 예시에서 reset: moving to HEAD~3이 실행되기 전, HEAD는 d4e5f6g(기능 C 추가)를 가리키고 있었다는 사실이 HEAD@{1}에 그대로 남아 있다.
기본 개념
23장에서 reset --hard로 커밋을 되돌리면 그 커밋들이 즉시 삭제되는 것이 아니라 unreachable(어느 브랜치에서도 참조되지 않는) 상태가 될 뿐이라고 설명했다. reflog는 정확히 이런 상황을 위한 기록이다 — 브랜치 참조(refs/heads/main)는 방금 과거로 옮겨졌지만, reflog에는 “옮기기 직전에 어디를 가리켰는지"가 그대로 남아 있으므로, 그 지점으로 다시 돌아가는 것이 가능하다.
| |
종류/세부
대표적인 복구 시나리오
시나리오 1: 잘못된 hard reset을 되돌리기
| |
시나리오 2: 강제 삭제한 브랜치의 커밋 복구
11장에서 다룬 git branch -D로 브랜치를 강제 삭제했다면, 브랜치 이름 자체는 사라지지만 그 브랜치에서 마지막으로 커밋했던 시점은 reflog에 남아 있을 수 있다.
| |
시나리오 3: 리베이스가 잘못됐을 때
15장·27장의 리베이스 도중 예상과 다른 결과가 나왔는데 이미 --abort할 시점을 놓쳤다면, reflog에서 리베이스 시작 전 상태를 찾아 되돌릴 수 있다.
| |
reflog의 한계
| 특성 | 내용 |
|---|---|
| 저장 위치 | 로컬 저장소(.git/logs/)에만 존재 |
| 원격 공유 여부 | 공유되지 않음(clone·push/pull로 전달되지 않음) |
| 보존 기간 | 기본적으로 도달 가능한 커밋은 90일, 도달 불가능한 커밋은 30일(설정으로 조정 가능) |
| 대상 | HEAD뿐 아니라 각 브랜치별로도 개별 reflog가 존재(git reflog show <branch>) |
reflog가 로컬에만 존재한다는 점이 중요하다 — 다른 컴퓨터나 원격 저장소에는 이 기록이 없으므로, 같은 실수를 다른 환경에서는 reflog로 복구할 수 없다.
주의사항·함정
reflog도 영구적인 백업은 아니다: 위 표에서 보듯 도달 불가능한 커밋은 기본 30일 후 가비지 컬렉션(36장) 대상이 될 수 있다. 실수를 발견했다면 가능한 한 빨리 reflog로 확인·복구하는 것이 안전하며, “나중에 처리해도 되겠지"라고 미루면 복구 창이 닫힐 수 있다.
git reflog expire나 git gc --aggressive를 실수로 실행하면 복구 여지가 줄어든다: 이런 명령은 정상적인 저장소 유지보수 목적이지만, 아직 검토하지 않은 최근 reflog 항목까지 만료시켜 복구 가능성을 낮출 수 있다. 복구가 필요한 상황이라면 이런 정리 명령을 먼저 실행하지 않는다.
reflog 항목 번호(HEAD@{N})는 새 작업을 할 때마다 계속 바뀐다: git reflog로 확인한 시점과 실제로 reset을 실행하는 시점 사이에 다른 Git 명령(체크아웃, 커밋 등)을 실행하면 번호가 밀릴 수 있다. 복구 직전에 다시 한번 git reflog로 정확한 번호(또는 해시)를 확인하는 편이 안전하다.
![Featured image of post [Git] 28. git reflog — 실수 복구](/post/git/git-reflog-command-recover-lost-commits/wordcloud_hu_5e4bfa9894799e22.webp)
![[Git] 26. git cherry-pick](/post/git/git-cherry-pick-command/wordcloud_hu_2a527478bbed902.webp)
![[Git] 27. git rebase -i — 인터랙티브 리베이스](/post/git/git-rebase-interactive-mode/wordcloud_hu_31933fe2155d80d4.webp)
![[Git] 28. git reflog — 실수 복구](/post/git/git-reflog-command-recover-lost-commits/wordcloud_hu_67933a4c82ea14b7.webp)
![[Git] 29. git stash — 임시 저장](/post/git/git-stash-command-temporary-storage/wordcloud_hu_57c9490aefdb3cf2.webp)
![[Git] 30. git clean — 미추적 파일 정리](/post/git/git-clean-command-remove-untracked-files/wordcloud_hu_73da61b3df7aabd.webp)
![[Git] 06. git status — 상태 확인](/post/git/git-status-command-check-working-tree-state/wordcloud_hu_47937000002ad2ce.webp)
![[Git] 09. git log — 히스토리 조회](/post/git/git-log-command-view-history/wordcloud_hu_bc1a6a01030ca9b3.webp)
![[Git] 23. git reset — soft/mixed/hard](/post/git/git-reset-command-soft-mixed-hard/wordcloud_hu_4a537338fdc7a2ba.webp)
![[Git] 44. 자주 발생하는 Git 에러와 해결법 총정리](/post/git/common-git-errors-and-solutions/wordcloud_hu_5251c239f8e16968.webp)
![[Git] 07. git diff — 변경 비교](/post/git/git-diff-command-compare-changes/wordcloud_hu_3b0ce1ca4361f1f6.webp)