
"Git을 공부하면서 쓰는 시리즈" 기초편 마지막 편입니다.
1편: git init · 2편: 브랜치 · 3편: git log 트리 · 4편: merge와 충돌 · 5편: 원격 저장소 · 6편: .gitignore · 7편: stash
시작하면서
Git을 쓰면서 가장 많이 찾아보게 되는 상황이 "되돌리기"입니다. 커밋 메시지를 잘못 썼거나, 파일을 엉뚱하게 수정했거나, 아예 커밋 자체를 없애고 싶을 때가 있습니다.
되돌리는 방법이 세 가지 있습니다. amend, revert, reset인데, 이름만 봐서는 뭐가 다른지 잘 모릅니다. 어떤 상황에 어떤 걸 써야 하는지가 핵심입니다.
세 가지 한 줄 비교
| amend | revert | reset | |
|---|---|---|---|
| 하는 일 | 직전 커밋 수정 | 되돌리는 커밋을 새로 만듦 | 커밋 자체를 지워버림 |
| 히스토리 | 변경됨 | 유지됨 | 변경됨 |
| push 후 사용 | 위험 | 안전 | 위험 |
하나씩 살펴봅니다.
git commit --amend — 직전 커밋 수정
가장 최근 커밋만 수정할 수 있습니다. 두 가지 용도로 씁니다.
커밋 메시지만 고치고 싶을 때
git commit --amend -m "올바른 커밋 메시지"
빠뜨린 파일을 커밋에 포함시키고 싶을 때
# 빠뜨린 파일 staging
git add forgotten-file.md
# 메시지는 그대로, 파일만 추가
git commit --amend --no-edit
--no-edit은 메시지 편집창 없이 그대로 사용한다는 옵션입니다.
주의사항
amend는 기존 커밋을 수정하는 게 아니라, 기존 커밋을 없애고 새 커밋을 만드는 것입니다. 커밋 ID(SHA-1 해시)가 바뀝니다.
이미 git push로 원격에 올라간 커밋을 amend하면, 로컬과 원격의 히스토리가 달라집니다. 혼자 쓰는 브랜치라면 git push --force로 덮어쓸 수 있지만, 다른 사람과 공유하는 브랜치에서는 하면 안 됩니다. 상대방의 히스토리가 꼬이거든요.
push 전에만 쓰는 게 안전합니다.
git revert — 되돌리는 커밋을 새로 만들기
revert는 특정 커밋의 변경사항을 반대로 되돌리는 새 커밋을 만듭니다. 기존 히스토리는 그대로 두고, 취소 내용을 기록으로 남기는 방식입니다.
git revert a9b3c12
커밋 메시지 편집창이 열립니다. 기본으로 Revert "커밋메시지" 형태가 채워져 있습니다. 저장하면 새 커밋이 생깁니다.
git log --oneline
f1e2d3c (HEAD -> main) Revert "README에 프로젝트 설명 추가"
a9b3c12 README에 프로젝트 설명 추가
3f2a1b4 첫 번째 커밋: README 추가
a9b3c12는 히스토리에 남아있고, 그걸 되돌린 f1e2d3c가 새로 생겼습니다.
revert가 유용한 이유
히스토리가 그대로 유지되기 때문에 이미 push한 커밋을 되돌릴 때 안전합니다. 다른 사람의 히스토리를 건드리지 않습니다.
"언제, 무엇을, 왜 되돌렸는지"도 기록으로 남습니다. 나중에 코드 리뷰나 이슈 추적에서 유용합니다.
메시지 편집창 없이 바로 커밋하려면
git revert a9b3c12 --no-edit
git reset — 커밋 자체를 지우기
reset은 현재 브랜치의 HEAD를 특정 커밋으로 되돌립니다. 그 이후의 커밋들은 히스토리에서 사라집니다.
옵션이 세 가지입니다. 이 부분이 reset에서 가장 헷갈리는 지점입니다.
--soft
커밋만 취소합니다. 변경사항은 Staging Area에 남습니다.
git reset --soft HEAD~1
HEAD~1은 "현재 커밋의 한 단계 이전"을 뜻합니다. 직전 커밋이 취소되고, 그 커밋에서 변경된 내용은 git add된 상태로 남습니다. 커밋 메시지를 바꾸거나 내용을 조금 고친 뒤 다시 커밋하고 싶을 때 씁니다.
--mixed (기본값)
커밋을 취소하고, 변경사항은 작업 디렉토리에 남습니다. Staging은 해제됩니다.
git reset HEAD~1
# 또는
git reset --mixed HEAD~1
git add하기 전 상태로 돌아갑니다. 파일 내용은 그대로이고 다시 수정해서 커밋할 수 있습니다.
--hard
커밋을 취소하고, 변경사항도 전부 삭제합니다.
git reset --hard HEAD~1
파일 내용까지 직전 커밋 시점으로 되돌아갑니다. 되돌릴 방법이 없으니 신중하게 써야 합니다. (엄밀히는 git reflog로 복구할 수 있지만, 그건 심화편에서 다룹니다.)
세 가지 비교
커밋 이전 상태: 파일 수정 → git add → git commit
--soft : 커밋만 취소 → 변경사항이 git add된 상태로 남음
--mixed: 커밋+add 취소 → 변경사항이 파일에는 남음
--hard : 커밋+add+수정 전부 취소 → 파일도 되돌아감
모르겠으면 --mixed가 가장 무난합니다. 파일은 남아있으니까 최악의 상황은 피할 수 있습니다.
reset도 push 후에는 위험합니다
amend와 마찬가지로 reset도 히스토리를 바꿉니다. 이미 push된 커밋을 reset하면 원격과 로컬이 달라지고, 공유 브랜치에서 쓰면 다른 사람의 히스토리가 꼬입니다. 로컬에서, push 전에 쓰는 게 원칙입니다.
상황별 선택 기준
정리하면 이렇습니다.
직전 커밋 메시지를 잘못 썼다
→ git commit --amend -m "새 메시지" (push 전이라면)
직전 커밋에 파일을 빠뜨렸다
→ git add <파일> 후 git commit --amend --no-edit
이미 push된 커밋을 되돌려야 한다
→ git revert <커밋ID> — 히스토리가 유지되어 안전
로컬에서 최근 커밋 몇 개를 없애고 다시 작업하고 싶다
→ git reset --mixed HEAD~N — 파일은 남기고 커밋만 취소
이 브랜치를 특정 시점으로 완전히 되돌리고 싶다
→ git reset --hard <커밋ID> — 변경사항도 전부 날아가므로 신중하게
파일 하나만 되돌리고 싶을 때
커밋 단위가 아니라 특정 파일 하나만 마지막 커밋 상태로 되돌리고 싶을 때는 2편에서 잠깐 소개한 git restore를 씁니다.
git restore README.md
저장되지 않은 변경사항이 사라지고 마지막 커밋 상태로 돌아옵니다. 이것도 되돌릴 수 없으니 주의합니다.
Staging Area에서만 빼고 싶다면(파일 내용은 유지):
git restore --staged README.md
이번 편 정리
| 명령어 | 하는 일 | push 후 사용 |
|---|---|---|
git commit --amend |
직전 커밋 수정 | ❌ 위험 |
git revert <ID> |
되돌리는 새 커밋 생성 | ✅ 안전 |
git reset --soft HEAD~N |
커밋만 취소, 변경사항 staging 유지 | ❌ 위험 |
git reset --mixed HEAD~N |
커밋+staging 취소, 파일은 유지 | ❌ 위험 |
git reset --hard HEAD~N |
커밋+파일 전부 취소 | ❌ 위험 |
git restore <파일> |
파일을 마지막 커밋 상태로 복원 | — |
git restore --staged <파일> |
파일을 staging에서만 제거 | — |
기초편을 마치며
8편에 걸쳐 Git의 기본 흐름을 전부 훑었습니다.
저장소 만들기 → 브랜치 → 히스토리 보기 → merge
→ 원격 저장소 → .gitignore → stash → 되돌리기
이 흐름을 이해하면 일상적인 Git 작업의 대부분을 커버할 수 있습니다. 물론 아직 모르는 것도 많습니다. rebase, cherry-pick, reflog, 브랜치 전략 같은 것들이요. 그건 심화편에서 이어갑니다.
다음 편부터는 Git이 내부적으로 어떻게 동작하는지, 그리고 히스토리를 더 정밀하게 다루는 방법을 다룹니다.
이 시리즈의 다른 글
- [기초편 1편] git init과 첫 커밋까지
- [기초편 2편] 브랜치, 어렵지 않아요
- [기초편 3편] git log를 트리로 보는 법
- [기초편 4편] merge와 충돌 해결
- [기초편 5편] 원격 저장소 연결하기
- [기초편 6편] .gitignore 제대로 쓰기
- [기초편 7편] stash — 작업 잠깐 숨기기
- [심화편 1편] Git 객체 모델 해부
'블로그, 컴퓨터 > DevOps' 카테고리의 다른 글
| Git 기초편 7편 — stash, 작업 잠깐 숨기기 (0) | 2026.05.11 |
|---|---|
| Git 기초편 6편 — .gitignore 제대로 쓰기 (0) | 2026.05.11 |
| Git 기초편 5편 — 원격 저장소 연결하기 (0) | 2026.05.11 |
| Git 기초편 4편 — merge와 충돌 해결 (0) | 2026.05.10 |
| Git 기초편 3편 — git log를 트리로 보는 법 (1) | 2026.05.10 |