홈/엔지니어/트러블슈팅/git reset --hard 후 커밋 복구 — r…
트러블슈팅중급ubuntumacoswindowsgitreflogreset

git reset --hard 후 커밋 복구 — reflog로 되돌리기

git reset --hard로 커밋을 잃었을 때 reflog와 ORIG_HEAD로 되살리는 순서를 정리했습니다. 복구가 안 되는 경우와 재발 방지도 다룹니다.

목차
  1. 30초 체크리스트
  2. 무엇이 복구되고 무엇이 안 되는가
  3. 1단계: reflog에서 reset 직전 위치 찾기
  4. 2단계: 새 브랜치로 붙잡아 두기
  5. 3단계: 원래 브랜치를 되돌릴지 결정
  6. 가장 빠른 길: ORIG_HEAD
  7. reflog에도 없을 때: fsck
  8. reflog 기록은 영원하지 않습니다
  9. 재발 방지
  10. 빠른 판정표

git reset --hard를 친 직후에 "방금 그 커밋이 없다"는 걸 알게 되는 경우가 있습니다. 브랜치가 가리키는 위치만 옮겨진 것이어서, 커밋 자체는 대개 한동안 저장소에 남아 있습니다. 이 글은 이미 reset --hard를 실행한 뒤 무엇을 어떤 순서로 하는지만 다룹니다. reset·revert·stash 전체 명령 비교는 Git 실수 복구 가이드를 보세요.

30초 체크리스트

  1. 더 이상 reset, checkout, gc를 하지 않습니다. 상황을 더 바꾸지 않는 게 먼저입니다.
  2. 지운 것이 커밋된 작업인지, 커밋 전 변경인지 구분합니다. 커밋된 것만 아래 방법으로 되살릴 수 있습니다.
  3. git reflog로 reset 직전 위치를 찾습니다.
  4. 찾은 커밋에 새 브랜치를 만들어 붙잡아 둡니다.
  5. 브랜치에서 내용이 맞는지 확인한 뒤 원래 브랜치를 옮길지 정합니다.

무엇이 복구되고 무엇이 안 되는가

잃어버린 것복구 가능성방법
reset으로 브랜치에서 빠진 커밋대개 가능reflog, ORIG_HEAD
reflog 기록이 사라진 커밋가능할 수 있음git fsck --full로 dangling commit 찾기
커밋하지 않은 tracked 파일 수정일반적으로 불가reset --hard는 이를 덮어씁니다
한 번도 add·commit하지 않은 새 파일(untracked)보통 reset --hard로 지워지지 않음(같은 경로에 커밋 파일이 있어 덮어쓰기를 방해하는 경우만 예외). 다른 사고로 사라졌다면 Git으로는 복구 불가에디터·IDE 로컬 히스토리, 백업 확인

공식 문서는 --hard를 인덱스와 작업 트리를 지정한 커밋 상태로 재설정하며, tracked 파일의 커밋되지 않은 변경은 버려지고 쓰기를 방해하는 untracked 파일은 삭제된다고 설명합니다(git-reset). 그래서 커밋하지 않은 수정은 reflog로 돌아오지 않습니다. reflog는 브랜치·HEAD가 가리킨 위치의 변화를 기록하는 장치이기 때문입니다(git-reflog).

1단계: reflog에서 reset 직전 위치 찾기

Bash
git reflog

예시 출력은 아래와 같은 모양입니다. 해시와 메시지는 설명을 위해 임의로 만든 값입니다.

TEXT
e5a1c07 HEAD@{0}: reset: moving to HEAD~1
9b3d6f2 HEAD@{1}: commit: Add retry logic
e5a1c07 HEAD@{2}: commit: Add config loader

HEAD@{0}이 reset 기록이고, 바로 아래 HEAD@{1}이 reset 직전에 있던 커밋입니다. HEAD@{n}은 "HEAD가 n번 이동하기 전 위치"를 뜻합니다(git-reflog). 내용을 더 보고 싶으면 아래를 씁니다.

Bash
git log -g          # reflog를 log 형식으로
git show HEAD@{1}   # 그 시점 커밋 내용 확인

2단계: 새 브랜치로 붙잡아 두기

바로 reset --hard로 되돌리기 전에, 찾은 커밋에 브랜치부터 만듭니다.

Bash
git branch recover-branch 9b3d6f2
git log --oneline recover-branch

브랜치가 가리키는 커밋은 reflog 기록이 만료되어도 도달 가능한 상태로 남습니다. 먼저 안전하게 잡아 두고, 그다음에 원래 브랜치를 옮겨도 늦지 않습니다. 같은 절차가 Pro Git의 데이터 복구 장에도 나옵니다.

3단계: 원래 브랜치를 되돌릴지 결정

내용이 맞다면 두 가지 중에서 고릅니다.

Bash
# (a) 원래 브랜치를 그 커밋으로 되돌림 — 현재 작업 트리 변경은 다시 덮어씁니다
git reset --hard 9b3d6f2

# (b) 현재 상태는 두고, 필요한 커밋만 가져옴
git cherry-pick 9b3d6f2

(a)를 실행하면 지금 작업 트리의 미커밋 변경이 다시 사라집니다. 먼저 git status로 확인하고 필요하면 git stash로 치워 두세요. 여러 커밋을 골라 옮기는 방법은 rebase·cherry-pick 가이드에 있습니다.

가장 빠른 길: ORIG_HEAD

git reset은 실행 전 HEAD 위치를 .git/ORIG_HEAD에 저장합니다. merge와 pull도 같은 값을 남깁니다(git-reset). reset 직후라면 reflog를 읽지 않고도 되돌릴 수 있습니다.

Bash
git reset --hard ORIG_HEAD

공식 문서의 "merge/pull 취소" 예시도 이 방식을 씁니다. 다만 그 사이에 reset·merge·pull을 한 번 더 했다면 ORIG_HEAD가 바뀌었을 수 있습니다. 확신이 없으면 reflog로 확인하세요.

작업 트리에 지키고 싶은 로컬 변경이 있을 때는 문서가 git reset --merge ORIG_HEAD를 더 안전한 선택으로 안내합니다. --hard는 그 변경을 버리기 때문입니다.

reflog에도 없을 때: fsck

저장소를 새로 clone했거나 기록이 만료됐다면 reflog에 없을 수 있습니다. reflog는 로컬 저장소 안의 기록이어서 다른 사람의 clone이나 원격 저장소에는 없습니다(git-reflog). 이럴 때는 어떤 참조도 가리키지 않는 객체를 찾습니다.

Bash
git fsck --full
# dangling commit 9b3d6f2... 같은 줄을 찾습니다
git branch recover-branch <dangling commit의 해시>

--lost-found를 붙이면 dangling commit은 .git/lost-found/commit/에, blob 등은 .git/lost-found/other/에 쓰입니다(git-fsck). 해시가 여러 개 나오면 git show <hash>로 하나씩 열어 내용을 확인합니다.

reflog 기록은 영원하지 않습니다

reflog 항목은 기본적으로 gc.reflogExpire 90일, 어느 브랜치에서도 도달할 수 없는 항목은 gc.reflogExpireUnreachable 30일 뒤 만료됩니다(git-reflog). reset으로 빠진 커밋은 도달 불가능 쪽에 해당할 가능성이 높으므로, 사고를 알았다면 가능한 한 빨리 복구합니다. 그 시점 설정은 git config gc.reflogExpireUnreachable로 확인할 수 있습니다. 설정에 따라 기본값과 다를 수 있습니다.

재발 방지

  • 팀 공유 브랜치에서는 reset --hard 대신 git revert를 씁니다. 기록을 지우지 않고 되돌리기 때문입니다.
  • reset 전에 git status와 git stash list로 지켜야 할 미커밋 변경이 있는지 봅니다.
  • 되돌릴지 불확실한 커밋 위에는 git branch backup-<날짜>로 표시를 남깁니다.
  • 이미 push한 브랜치를 reset한 뒤 강제 push가 필요해지면 거절 사유를 git push rejected 해결에서 확인합니다.

빠른 판정표

상황첫 행동
방금 reset --hard를 쳤다git reset --hard ORIG_HEAD 전에 git reflog로 위치 확인
며칠 전 reset했다git reflog, 기록이 있으면 브랜치부터 생성
reflog에 없다git fsck --full에서 dangling commit 탐색
커밋 안 한 수정을 잃었다Git으로는 어렵다. 에디터 로컬 히스토리·백업 확인
팀 브랜치에 reset을 하려 한다멈추고 git revert 검토

reset --hard는 브랜치 포인터를 옮기는 명령입니다. 커밋을 되살리는 일은 reflog에서 해시 하나를 찾아 브랜치를 붙이는 것으로 끝나는 경우가 많습니다.

#git#reflog#reset#복구#troubleshooting
편집 안내 · Editorial Note

AI 도구가 초안 작성에 사용될 수 있습니다. 명령어의 실행 여부와 검증 환경은 각 가이드에 기재된 근거를 확인하세요. 적용 전 사용 중인 버전의 공식 문서를 확인하고, 오류는 이메일로 알려주세요. 이메일로 제보

주제 관련 공식 문서(자동 연결 · 문장별 근거 아님)Git 공식 문서 ↗

질문 & 답변 (Q&A)

이 가이드에 대해 궁금한 점을 질문해보세요. 확인 후 답변드립니다.