git reset --hard 취소하기: 날아간 커밋 되살리는 reflog 활용법
프로젝트 마감이 코앞인데 엉킨 브랜치를 정리해보겠다고 git reset --hard를 입력했다가, 내가 며칠 동안 작업한 커밋까지 몽땅 날려버렸을 때의 그 절망감... 정말 말로 다 표현할 수 없죠. 저도 예전에 로컬에서만 작업해 둔 코드를 실수로 날려버리고 모니터 앞에서 몇 분 동안 멍하니 앉아있었던 기억이 납니다. 😭
하지만 너무 걱정하지 마세요! 다행히도 Git은 우리가 생각하는 것보다 훨씬 철저하고 친절한 녀석입니다. 여러분이 의도적으로 .git 폴더를 삭제하지 않는 이상, Git은 로컬 저장소에서 일어난 거의 모든 행동을 조용히 기록하고 있거든요. 오늘은 그 비밀의 일기장인 git reflog를 열어서 잃어버린 커밋을 구출해 내는 방법을 차분하게 짚어보려고 합니다. 심호흡 한 번 하시고, 천천히 따라와 주세요.
비밀의 일기장, git reflog란 무엇일까? 🤔
보통 우리가 커밋 내역을 볼 때 git log를 사용하죠. 하지만 git reset 명령어로 브랜치의 상태를 과거로 돌려버리면, git log에서는 되돌아간 시점 이후의 커밋들이 보이지 않게 됩니다. 마치 역사책에서 특정 페이지 이후가 찢겨 나간 것처럼요.
반면 git reflog(Reference logs)는 여러분의 로컬 저장소에서 HEAD가 움직인 모든 궤적을 기록하는 블랙박스입니다. 커밋을 하든, 브랜치를 바꾸든, 심지어 방금 한 것처럼 reset을 하든 모든 액션이 시간순으로 낱낱이 기록되어 있습니다.
git log와 git reflog의 차이점 📊
| 비교 항목 | git log | git reflog |
|---|---|---|
| 기록 대상 | 현재 브랜치의 커밋 히스토리 | 로컬 HEAD의 모든 이동 내역 |
| 리셋(Reset) 후 | 리셋되어 날아간 커밋은 보이지 않음 | 리셋 명령을 실행한 기록까지 모두 보임 |
| 공유 범위 | 원격 저장소(GitHub 등)와 공유됨 | 내 컴퓨터(로컬)에만 존재함 |
reflog는 오직 내 컴퓨터에만 남는 기록입니다. 따라서 내가 실수한 프로젝트 폴더(로컬 저장소)에서 바로 명령어를 실행해야 복구가 가능합니다.
날아간 커밋을 되살리는 3단계 복구 가이드 🚑
이제 본격적으로 잃어버린 커밋을 찾아보겠습니다. 터미널을 열고 아래 단계들을 천천히 따라와 주세요.
Step 1: reflog 출력하기
터미널에 다음 명령어를 입력합니다.
$ git reflog
Step 2: 돌아가고 싶은 시점 찾기
출력된 목록을 보면 가장 최근 행동이 맨 위(HEAD@{0})에 있습니다. 여기서 우리가 눈여겨봐야 할 것은 '실수하기 바로 직전'의 커밋 해시나 HEAD 인덱스입니다.
a1b2c3d HEAD@{0}: reset: moving to HEAD~2 // <- span="">
e4f5g6h HEAD@{1}: commit: 로그인 폼 UI 구현 완료 // <- span="">
7i8j9k0 HEAD@{2}: commit: 로그인 버튼 컴포넌트 추가->->
Step 3: 해당 시점으로 다시 Reset 하기
목표 지점을 찾았다면, 해당 해시값(e4f5g6h)이나 참조 인덱스(HEAD@{1})를 복사해서 다시 reset 해줍니다. 이미 엎질러진 물을 다시 주워 담는 마법의 명령어입니다.
$ git reset --hard HEAD@{1}
위 과정을 거치고 나면 터미널에 HEAD is now at e4f5g6h 로그인 폼 UI 구현 완료라는 메시지가 뜨면서 코드들이 기적처럼 원래 자리로 돌아와 있을 겁니다.
복구 시점 찾기 연습 🧮
실제로 git reflog를 쳐보면 로그가 너무 길어서 눈에 잘 안 들어올 때가 있죠. 아래에 여러분의 터미널에 뜬 로그를 복사해서 붙여넣어 보세요. 어디로 돌아가야 할지 힌트를 찾아드릴게요.
터미널 로그 분석기 🔍
주의해야 할 예외 상황들 👩💻👨💻
이처럼 강력한 reflog 기능이지만, 안타깝게도 만능은 아닙니다. 복구가 불가능한 슬픈(?) 상황도 존재하니 미리 알아두시는 것이 좋습니다.
- 커밋하지 않은 작업물:
git add나git commit을 한 번도 하지 않고 워킹 디렉토리(Working Directory)에만 있던 코드들은reset --hard를 치는 순간 영영 사라집니다. Git이 추적해 본 적이 없기 때문이에요. - 기록 만료: reflog의 기본 보존 기간은 90일입니다. 몇 달 전에 실수한 기록을 이제 와서 살리기는 어렵습니다.
그래서 많은 시니어 개발자들이 "의미 없는 코드라도 일단 commit은 자주 남겨라"라고 조언하는 거랍니다. Git의 안전망 안에 코드를 던져두면 어떻게든 살려낼 구멍이 생기니까요.
핵심 요약 카드 📝
당황스러운 상황에 바로 꺼내 볼 수 있도록 오늘 배운 내용을 한 장의 카드로 정리해 보았습니다.
git reset 복구 3단계
자주 묻는 질문 ❓
revert는 이전 커밋의 내용을 취소하는 '새로운 커밋'을 추가하여 히스토리를 유지하는 안전한 방식이고, reset은 커밋 히스토리 자체를 과거로 싹둑 잘라버리는 방식입니다. 협업 중인 브랜치라면 revert를 권장합니다.git push -f (강제 푸시)를 사용해야 하지만, 팀원들과 코드가 엉킬 수 있으니 반드시 팀 내 공유 후 진행하세요.git branch [새브랜치명] [해시값] 명령어를 입력하면 브랜치도 고스란히 복구됩니다.개발을 하다 보면 누구나 한 번쯤 치명적인 실수를 합니다. 하지만 오늘 알아본 것처럼, Git이라는 도구는 생각보다 우리를 위해 많은 안전장치를 마련해 두고 있답니다. 이 글이 패닉에 빠진 여러분의 멘탈과 소중한 코드를 무사히 구출해 내는 데 도움이 되었길 바랍니다. 복구 중에 막히는 부분이 있다면 댓글로 알려주세요~ 같이 해결해 봐요! 😊