되돌리기 & 복구 매뉴얼

AI가 망친 변경, 잘못 고친 파일·스테이징·커밋을 안전하게 되돌리고 잃어버린 작업을 복구하는 명령 모음  |  공식 문서: git-scm.com/docs

대상 버전git 2.5x (2.50.1 기준)
참조 문서 URLgit-restore · git-reset · git-revert · git-stash · git-reflog
문서 수집일2026-06-16
버전 확인 방법git --version 으로 설치된 버전을 확인한다.
개정 시 확인 사항명령·옵션 변경 여부는 git-scm.com에서 다시 확인한다.

되돌리기 명령 트리

되돌리기가 어렵게 느껴지는 이유는 명령이 많아서가 아니라 되돌릴 수 있는 자리가 여러 곳이기 때문이다. 먼저 무엇을 되돌릴지 정하면 쓸 명령은 거의 자동으로 정해진다. 아래 트리는 "어디를 되돌리나"를 기준으로 명령을 묶은 것이다.

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영역)

💡 배경 개념: 되돌리기는 '어디를' 되돌릴지부터

바이브 코딩에서 AI는 한 번에 많은 파일을 고친다. 결과가 마음에 안 들 때 "되돌려"라고 하기 전에, 그 변경이 지금 어느 자리에 있는지부터 알아야 한다. 글을 쓸 때 '방금 친 글자', '저장 안 한 문단', '저장한 파일', '예전에 보낸 메일'을 되돌리는 방법이 각각 다른 것과 같다.

Git에는 되돌릴 수 있는 자리가 크게 네 곳 있다. ① 작업 폴더(Working Tree)는 지금 편집 중인 파일, ② 스테이징(Index)add로 담아 둔 커밋 대기 상태, ③ 마지막 커밋(HEAD)은 가장 최근에 확정한 버전, ④ 과거 커밋들은 이력에 쌓인 옛 버전들이다.

① 작업 폴더 Working Tree ② 스테이징 Index ③ 마지막 커밋 HEAD ④ 과거 커밋들 이력(History) git restore restore --staged reset --soft reset --mixed (기본) reset --hard ⚠ 작업 폴더까지 전부 버림 revert (새 커밋) 막대 = 그 명령이 바꾸는 범위 · amend는 ③ 수정 · stash는 ①을 잠시 보관 · reflog는 복구 구명줄

되돌릴 자리별 명령 한눈에

되돌릴 자리무엇인가쓰는 명령
① 작업 폴더
(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 <파일> — 수정을 버리고 되돌리기

작업 폴더에서 파일을 고쳤는데 그 수정을 통째로 버리고 싶을 때 쓴다. 기본적으로 스테이징(인덱스) 상태로 되돌리며, 스테이징한 적이 없으면 마지막 커밋 상태로 돌아간다. AI가 한 파일을 엉뚱하게 고쳐 놓았고 아직 add 전이라면, 이 명령 하나로 깔끔히 원복할 수 있다.

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로 무엇이 사라지는지 확인한다. 병기: git checkout -- 파일은 같은 동작의 옛 명령이다.

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 (기본) 대상으로 이동 해제(언스테이징) 그대로 중간 — 변경은 남고 다시 add 필요
--hard 대상으로 이동 해제 덮어씀(변경 삭제) ⚠️ 높음 — 커밋 안 된 변경 영구 손실, 복구 불가

풀어서 설명하면:

# 최근 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과의 핵심 차이이며, 그래서 이미 push된 공유 브랜치에서도 안전하다. 실행 전 작업트리가 깨끗해야 한다.

git revert abc1234           # 그 커밋을 되돌리는 새 커밋 생성
git revert HEAD              # 직전 커밋을 되돌리는 새 커밋

# 커밋은 만들지 말고 변경만 적용 (여러 개를 한 번에 묶고 싶을 때)
git revert -n abc1234 def5678
git commit -m "두 커밋을 되돌림"

# 병합(merge) 커밋을 되돌릴 땐 어느 부모로 되돌릴지 지정 필요
git revert -m 1 <merge커밋>
📌 reset vs revert, 무엇을 쓸까? 기준은 단 하나, "이미 push해서 남과 공유됐는가"다. 아직 내 컴퓨터에만 있으면 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 --hardrebase로 커밋을 잃은 것 같을 때, 여기서 사라진 커밋의 위치를 찾아 되살릴 수 있다.

git reflog                   # HEAD가 거쳐 온 위치 목록 보기

# 예시 출력
# a1b2c3d HEAD@{0}: reset: moving to HEAD~3
# e4f5a6b HEAD@{1}: commit: 중요한 작업   ← 잃어버린 줄 알았던 커밋

# 그 지점으로 되살리기
git reset --hard HEAD@{1}
🛟 막혔을 때의 구명줄이다. "reset --hard로 커밋이 날아간 것 같다"면 당황하지 말고 먼저 git reflog를 본다. 커밋은 보통 바로 사라지지 않고 reflog에 남아 있어, HEAD@{n}으로 돌아갈 수 있다.
reflog 항목은 영원하지 않다. 기본적으로 약 90일(도달 불가 상태인 항목은 30일) 뒤 만료된다. 또한 reflog는 내 컴퓨터에만 있는 로컬 기록이라, 다른 사람의 reflog나 GitHub에는 없다. 그러니 복구는 일이 벌어진 컴퓨터에서, 너무 늦기 전에 한다.

9. 되돌리기 안전 가이드

되돌리기 명령은 강력한 만큼 잘못 쓰면 작업을 잃을 수 있다. 입문자는 아래 규칙만 지켜도 큰 사고를 피할 수 있다. 핵심 판단 기준은 "이미 push해서 공유됐는가" 하나다.

상황안전한 선택
아직 push 안 함 (내 컴퓨터에만) reset · --amend · rebase로 이력 정리해도 OK
이미 push 함 (남과 공유됨) revert만 사용 (이력을 보존)
  1. 공유 전이면 마음껏, 공유 후면 revert. push 전 로컬 커밋은 reset·amend로 정리해도 된다. push해서 남이 받아 갔다면 revert만 쓴다.
  2. 파괴적 명령 전엔 status부터. git reset --hardgit restore는 저장 안 한 변경을 지운다. 실행 전 git status로 잃을 것이 없는지 확인한다.
  3. 막히면 reflog. 커밋을 잃은 것 같으면 git reflog가 구명줄이다.
  4. 정말 위험한 작업 전엔 백업 브랜치.reset·rebase 전에 현재 지점을 가지로 따 두면 언제든 돌아올 수 있다.
  5. push --force는 피한다. 꼭 필요하면 그동안 원격이 바뀌지 않았을 때만 진행하는 git push --force-with-lease를 쓴다.
# 위험한 작업 전, 지금 위치를 백업 브랜치로 따 두기
git branch backup        # 현재 상태를 'backup' 브랜치로 표시
# ...이후 reset/rebase 등을 진행하다 잘못되면
git reset --hard backup  # 따 둔 지점으로 안전하게 복귀
가장 위험한 두 명령은 git reset --hardgit restore다. 둘 다 커밋하지 않은 변경을 되살릴 수 없게 지운다. 손이 가기 전에 한 번 멈추고 git status를 확인하는 습관을 들인다.
git push --force는 원격의 커밋을 덮어써 다른 사람의 작업을 잃게 할 수 있고 지정한 모든 ref에 적용된다. 공유된 커밋은 reset·force가 아니라 언제나 revert로 되돌린다.

참고 링크


git 2.5x(2.50.1) 기준 | 2026년 6월