되돌리기 & 복구 매뉴얼
잘못 고친 파일·스테이징·커밋을 안전하게 되돌리고, 잃어버린 작업을 복구하는 명령어 모음 | 공식 문서: git-scm.com/docs
git --version명령어 트리 (Command Tree)
git (되돌리기·복구) │ ├── [작업 폴더·스테이징 취소] │ ├── git restore <file> 작업 폴더의 수정을 버리고 마지막 저장 상태로 │ └── git restore --staged <file> add를 취소 (스테이징에서 내림) │ ├── [커밋 되돌리기] │ ├── git reset --soft <대상> 커밋만 풀고 변경은 스테이징에 남김 │ ├── git reset --mixed <대상> (기본) 커밋·add 풀고 작업 폴더는 유지 │ ├── git reset --hard <대상> ⚠️ 전부 되돌림 (변경 영구 삭제) │ ├── git revert <커밋> 되돌리는 새 커밋 생성 (이력 보존·안전) │ └── git commit --amend 직전 커밋 메시지·내용 고치기 │ ├── [잠깐 치워두기] │ ├── git stash 작업 중인 변경을 임시 저장하고 깨끗이 │ ├── git stash list 치워둔 목록 보기 │ └── git stash pop 치워둔 변경 되살리기 │ └── [응급 복구] └── git reflog HEAD 이동 기록 → 잃어버린 커밋 찾기
restore, 스테이징은 restore --staged, 커밋은 (혼자) reset / (공유됨) revert. 잃어버린 것 같으면 reflog가 마지막 구명줄입니다.1. 어디를 되돌릴 것인가 (4영역)
💡 배경 개념: 되돌리기는 '어디를' 되돌릴지부터
Git에서 '되돌리기'가 어렵게 느껴지는 이유는 명령이 많아서가 아니라, 되돌릴 수 있는 자리가 여러 곳이기 때문입니다. 마치 글을 쓸 때 '방금 친 글자', '저장 안 한 문단', '저장한 파일', '예전에 보낸 메일'을 되돌리는 방법이 각각 다른 것과 같습니다. 어디를 되돌릴지만 정하면, 쓸 명령은 거의 자동으로 정해집니다.
Git에는 되돌릴 수 있는 자리가 크게 네 곳 있습니다. ① 작업 폴더(Working Tree)는 지금 편집 중인 파일, ② 스테이징(Index)은 add로 담아 둔 커밋 대기 상태, ③ 마지막 커밋(HEAD)은 가장 최근에 확정한 버전, ④ 과거 커밋들은 이력에 쌓인 옛 버전들입니다.
되돌릴 자리별 명령 한눈에
| 되돌릴 자리 | 무엇인가 | 쓰는 명령 |
|---|---|---|
| ① 작업 폴더 (Working Tree) |
지금 편집 중인, 아직 add 안 한 파일 수정 | git restore <file> |
| ② 스테이징 (Index) |
add로 담아 둔 커밋 대기 변경 |
git restore --staged <file> |
| ③ 마지막 커밋 (HEAD) |
방금 확정한 직전 커밋 | git commit --amend / git reset |
| ④ 과거 커밋들 | 이력에 쌓인 옛 버전 | git reset(혼자) / git revert(공유됨) |
git status를 치세요. 어떤 파일이 작업 폴더에만 있는지, 스테이징됐는지, 커밋됐는지 알려 줍니다. 이걸 알아야 위 표에서 어떤 명령을 쓸지 정할 수 있습니다.2. 작업 폴더 되돌리기 (restore)
git restore <파일> — 수정을 버리고 되돌리기
작업 폴더에서 파일을 고쳤는데 그 수정을 통째로 버리고 싶을 때 씁니다. 기본적으로 스테이징(인덱스) 상태로 되돌리며, 스테이징한 적이 없으면 마지막 커밋 상태로 돌아갑니다. 기본 복구 소스는 인덱스입니다.
git restore index.html # 이 파일의 수정을 버리고 되돌리기 git restore . # 작업 폴더의 모든 수정을 되돌리기 # 특정 과거 커밋의 버전으로 되돌리기 (-s = --source) git restore --source=HEAD~2 index.html git restore -s abc1234 index.html
git restore는 저장(커밋)하지 않은 변경을 지웁니다. 한번 버린 수정은 되살릴 수 없습니다(작업 폴더의 변경은 reflog로도 복구 불가). 실행 전에 반드시 git status로 무엇이 사라지는지 확인하세요.3. 스테이징 취소 (restore --staged)
git restore --staged <파일> — add 취소
git add를 했다가 "이건 이번 커밋에 안 넣을래" 싶을 때 씁니다. 스테이징에서만 내릴 뿐, 파일 내용은 그대로 둡니다(수정이 사라지지 않습니다). HEAD(마지막 커밋) 기준으로 인덱스를 되돌립니다.
git restore --staged index.html # 이 파일을 스테이징에서 내림 (-S 와 동일) git restore --staged . # 스테이징한 전부를 내림
git reset <파일>과 같은 효과입니다. 즉 git restore --staged 파일과 git reset 파일은 둘 다 'add 취소'입니다. add의 정확한 반대 동작이라고 생각하면 됩니다. 둘 다 파일 내용은 건드리지 않으니 안심하고 써도 됩니다.4. reset — 커밋 풀기
git reset은 현재 브랜치가 가리키는 위치(HEAD)를 지정한 대상 커밋으로 되감습니다. 어디까지 같이 되감을지는 세 가지 모드로 정합니다. 이 셋의 차이가 reset의 전부입니다.
| 모드 | HEAD(커밋 위치) | 인덱스(스테이징) | 작업 폴더 |
|---|---|---|---|
--soft |
대상으로 이동 | 그대로 유지 | 그대로 유지 |
--mixed (기본) |
대상으로 이동 | 대상에 맞춤 | 그대로 유지 |
--hard |
대상으로 이동 | 대상에 맞춤 | 대상에 맞춤 ⚠️ |
풀어서 설명하면:
--soft— 커밋만 풀고, 그 변경은 다시 스테이징에 남겨 둡니다. 여러 커밋을 하나로 합칠 때 유용합니다.--mixed(기본) — 커밋과add를 풀어 변경을 unstaged(작업 폴더에만 있는) 상태로 남깁니다. 작업 폴더 내용은 그대로입니다.--hard— HEAD·인덱스·작업 폴더를 전부 대상에 맞춥니다. 커밋하지 않은 변경은 사라집니다.
# 최근 3개 커밋을 풀어서 하나로 다시 커밋하고 싶을 때 git reset --soft HEAD~3 git commit -m "세 단계 작업을 하나로 정리" # 마지막 커밋만 풀고 변경은 작업 폴더에 되돌려 받기 (기본 모드) git reset HEAD~1 # 경로를 주면 = 그 파일 스테이징 취소 (모드 아님) git reset index.html # = git add 의 반대 = git restore --staged
git reset --hard는 커밋하지 않은 변경을 영구 삭제하는 파괴적 명령입니다. 작업 폴더와 스테이징의 모든 변경이 사라지므로, 실행 전 git status로 잃을 것이 없는지 꼭 확인하세요. (이미 커밋된 내용은 reflog로 되살릴 여지가 있지만, 커밋 안 한 변경은 그렇지 않습니다.)5. revert — 안전한 되돌리기
git revert는 과거 커밋의 변경을 되돌리는 '새 커밋'을 추가로 만듭니다. 즉 이력을 지우는 게 아니라, "그 커밋을 취소한다"는 사실을 새 커밋으로 남깁니다. 이력이 그대로 보존되는 점이 reset과의 핵심 차이입니다.
git revert abc1234 # 그 커밋을 되돌리는 새 커밋 생성 # 커밋은 만들지 말고 변경만 적용 (여러 개를 한 번에 묶고 싶을 때) git revert -n abc1234 def5678 git commit -m "두 커밋을 되돌림" # 병합(merge) 커밋을 되돌릴 땐 어느 부모로 되돌릴지 지정 필요 git revert -m 1 <merge커밋>
reset으로 깔끔히 풀어도 됩니다. 그러나 이미 push된 커밋은 revert를 쓰세요. reset으로 공유된 이력을 바꾸면 동료의 저장소와 어긋나 충돌이 납니다. revert는 이력을 안 바꾸므로 안전합니다.reset vs revert vs restore 비교
| 명령 | 되돌리는 대상 | 이력 변화 | 언제 쓰나 |
|---|---|---|---|
git restore |
작업 폴더 / 스테이징 | 없음 (커밋 안 건드림) | 아직 커밋 안 한 수정·add를 취소 |
git reset |
커밋 위치(HEAD) | 이력 다시 씀 (커밋이 풀림) | 혼자 쓰는(push 전) 커밋 정리 |
git revert |
과거 커밋의 변경 | 보존 (되돌리는 새 커밋 추가) | 공유된(push 후) 커밋 되돌리기 |
6. 직전 커밋 수정 (commit --amend)
방금 한 커밋의 메시지를 잘못 썼거나, 파일 하나를 빠뜨렸을 때 씁니다. 새 커밋을 또 쌓는 대신, 마지막 커밋을 고쳐서 다시 만듭니다.
# 메시지만 고치기 git commit --amend -m "로그인 검증 추가 (오타 수정)" # 빠뜨린 파일을 직전 커밋에 합치기 git add forgotten.js git commit --amend --no-edit # --no-edit: 메시지는 그대로 두고 내용만 합침
--amend는 직전 커밋을 새 커밋으로 대체합니다(이력을 다시 씀). 따라서 아직 push하지 않은, 공유 전 커밋에만 쓰세요. 이미 push한 커밋을 amend하면 reset과 마찬가지로 공유 이력이 어긋납니다.7. stash — 잠깐 치워두기
작업하던 중인데 아직 커밋하기는 애매하고, 잠깐 다른 일(예: 다른 브랜치로 이동)을 해야 할 때 씁니다. git stash는 현재 변경을 임시 서랍에 치워 두고 작업 폴더를 마지막 커밋 상태로 깨끗이 되돌립니다. 나중에 꺼내 그대로 이어서 작업할 수 있습니다.
git stash # 변경을 치워 두기 (= git stash push) git stash list # 치워 둔 목록 보기 git stash pop # 가장 최근 것을 되살리고 목록에서 제거 git stash apply # 되살리되 목록에는 그대로 남겨 둠 git stash show # 치워 둔 변경 내용 보기 git stash drop # 치워 둔 항목 하나 삭제 git stash clear # 치워 둔 항목 전부 삭제
| 명령 | 동작 |
|---|---|
git stash | 추적 중인 파일의 변경을 치워 두고 작업 폴더를 깨끗이 함 (= push) |
git stash pop | 치워 둔 변경을 되살리고 목록에서 제거 |
git stash apply | 되살리되 목록에 그대로 유지 (여러 곳에 적용할 때) |
git stash -u | 미추적(untracked) 파일까지 함께 치워 둠 (--include-untracked) |
git stash -a | 무시(ignored) 파일까지 전부 치워 둠 (--all) |
add한 적 없는 파일은 -u를 붙여야 함께 들어갑니다. 특정 항목은 stash@{0}(가장 최신), stash@{1}처럼 번호로 가리킵니다.8. reflog — 응급 복구
git reflog는 HEAD와 브랜치 끝이 '언제, 어디로 움직였는지'를 기록한 로컬 일지입니다. 커밋·리셋·체크아웃·리베이스 등으로 위치가 바뀔 때마다 한 줄씩 남습니다. reset --hard나 rebase로 커밋을 잃은 것 같을 때, 여기서 사라진 커밋의 위치를 찾아 되살릴 수 있습니다.
git reflog # HEAD가 거쳐 온 위치 목록 보기
# 예시 출력
# a1b2c3d HEAD@{0}: reset: moving to HEAD~3
# e4f5g6h HEAD@{1}: commit: 중요한 작업 ← 잃어버린 줄 알았던 커밋
# 그 지점으로 되살리기
git reset --hard HEAD@{1}
reset --hard로 커밋이 날아간 것 같다"면 당황하지 말고 먼저 git reflog를 보세요. 커밋은 보통 바로 사라지지 않고 reflog에 남아 있어, HEAD@{n}으로 돌아갈 수 있습니다.reflog 항목은 영원하지 않습니다. 기본적으로 약 90일(도달 불가 상태인 항목은 30일) 뒤 만료됩니다. 또한 reflog는 내 컴퓨터에만 있는 로컬 기록이라, 다른 사람의 reflog나 GitHub에는 없습니다. 그러니 복구는 일이 벌어진 컴퓨터에서, 너무 늦기 전에 하세요.9. 되돌리기 안전 가이드
되돌리기 명령은 강력한 만큼 잘못 쓰면 작업을 잃을 수 있습니다. 입문자는 아래 다섯 가지만 지켜도 큰 사고를 피할 수 있습니다.
| 상황 | 안전한 선택 |
|---|---|
| 아직 push 안 함 (내 컴퓨터에만) | reset · --amend · rebase로 이력 정리해도 OK |
| 이미 push 함 (남과 공유됨) | revert만 사용 (이력을 보존) |
- 공유 전이면 마음껏, 공유 후면 revert. push 전 로컬 커밋은
reset·amend로 정리해도 됩니다. push해서 남이 받아 갔다면revert만 쓰세요. - 파괴적 명령 전엔 status부터.
git reset --hard와git restore는 저장 안 한 변경을 지웁니다. 실행 전git status로 잃을 것이 없는지 확인하세요. - 막히면 reflog. 커밋을 잃은 것 같으면
git reflog가 구명줄입니다. - 정말 위험한 작업 전엔 백업 브랜치. 큰
reset·rebase전에 현재 지점을 가지로 따 두면 언제든 돌아올 수 있습니다.
# 위험한 작업 전, 지금 위치를 백업 브랜치로 따 두기 git branch backup # 현재 상태를 'backup' 브랜치로 표시 # ...이후 reset/rebase 등을 진행하다 잘못되면 git reset --hard backup # 따 둔 지점으로 안전하게 복귀
git reset --hard와 git restore입니다. 둘 다 커밋하지 않은 변경을 되살릴 수 없게 지웁니다. 손이 가기 전에 한 번 멈추고 git status를 확인하는 습관을 들이세요.참고 링크
- git restore 공식 문서
- git reset 공식 문서
- git revert 공식 문서
- git stash 공식 문서
- git reflog 공식 문서
- → 이 섹션의 실습 예시로 이동
Git 2.54.0 기준 · 한국어 교육 자료 · 문서 수집일 2026년 6월 13일
공식 문서: git-scm.com/docs