Git 되돌리기, Git 수정 : git restore, git revert, git reset

들어가며

코딩을 하다보면 특정 시점으로 되돌아가야 하는 경우가 종종 발생합니다. 이런 경우 git restore, git revert, git reset을 사용합니다. 하지만 저 또한 정리가 제대로 안 되어서 할 때 마다 고생을 하고 시간을 많이 소요되게 되어 이번 기회에 블로그에 정리하게 되었습니다. “Git 되돌리기” 어떤 경우에 어떻게 사용하는 걸까요?

우선은 특정 commit 시점으로 되돌리는 명령어들을 테이블로 간단히 정리 한 뒤,

실제 해당 명령어들이 어떻게 작동 되는지 그림과 함께 정리해보았습니다.

Git 되돌리기 명령어 요약 정리

Git restore

git restore [파일명]

윈도우의 Ctrl+Z와 같은 기능을 하는 굉장히 유용한 명령어 입니다.

Git history가 남기 때문에 얼마든지 유용하게 사용할 수 있습니다.

옵션설명시나리오파일 변경스테이징 변경커밋 변경Git 기록에 대한 위험도
-s, --source복원할 커밋을 지정합니다
(예: 마지막 커밋의 경우 --source=HEAD)
특정 커밋이나 브랜치에서 변경 사항을 선택적으로 복원할 때 유용OOX낮음
--staged스테이징 영역에서 복원합니다.해당 커밋 메시지에 어울리지 않은 변경 파일들을 스테이징 하지 않는 경우 유용XOX낮음
--worktree작업 디렉터리에서 복원합니다.아직 준비되지 않은 작업 디렉터리의 변경 사항을 되돌릴 때 유용OXX낮음

Git revert

git revert [commit ID]

되돌리기를 수행하면서 새 커밋을 생성합니다.

공식적으로 코드를 되돌린 것을 commit 기록으로 명시하고 싶을 때 사용하면 좋습니다.

예를 들어 매개변수나, 로직을 변경했는데 해당 변경사항이 옳지 않음이 증명되었을 때 사용하면 좋습니다.

옵션설명시나리오파일 변경스테이징 변경커밋 변경Git 기록에 대한 위험도
-n, --no-commit되돌리기를 수행하지만 새 커밋을 생성하지 않아 추가 수정이 가능합니다.특정 commit의 오류를 인정하고 이를 바고 잡고 싶은 경우 유용O?X낮음

Git reset

git reset [commit ID]

단순한 되돌리기가 아닙니다. Git의 commit 기록 자체를 지워버리고 싶은 경우 사용합니다.

원격 저장소와 연결된 경우, git commit을 지우는 것은 git log를 엉망으로 만들 수 있습니다.

웬만해서는 git restore와 git revert를 사용해서 수정을 끝내는 걸 권장합니다.

“HEAD를 지정된 커밋으로 재설정한다”의 설명에서 HEAD는 가장 마지막 commit을 의미합니다. 때문에 “HEAD를 지정된 커밋으로 재설정한다”의 의미는 git history를 해당 commit으로 되돌린다는 의미입니다.

옵션설명시나리오파일 변경스테이징 변경커밋 변경Git 기록에 대한 위험도
--softHEAD를 지정된 커밋으로 재설정합니다.

하지만 인덱스 및 실제 파일 내용들은 그대로 둡니다.
1. 로컬에서 커밋을 완료했으나 원격 저장소로 보내기 전에
커밋을 취소하고 파일에서 추가 수정이 필요한 경우

2. 파일의 변경사항은 유지하면서 커밋만 수정하고 싶은 경우
XXO높음
--mixed (기본값)HEAD를 지정된 커밋으로 재설정하면서 인덱스도 재설정 합니다.

실제 파일 내용들은 그대로 둡니다.
1. 로컬에서 커밋을 완료했으나 원격 저장소로 보내기 전에
커밋을 취소하고 파일에서 추가 수정이 필요한 경우

2. 파일의 변경사항은 유지하면서 커밋만 수정하고 싶은 경우
XOO높음
--hard모든 것을 지정된 커밋으로 되돌립니다.빠꾸 없는 롤백….;;OOO높음

Git restore 시나리오 : Ctrl + z 과 같은 git 되돌리기

다음과 같은 git history로 구성된 파일들이 있는 경우를 예로 들어보겠습니다.

commit log는 저장 시점에 대한 기록이기 때문에 이는 건들지 않고 특정 시점들로 되돌아갈 수 있습니다.

저장 시점이 전부 그대로 있기 때문에 언제든 가장 마지막 시점으로 되돌아올 수도 있습니다.

-s 옵션을 사용해서 특정 commit 시점으로 돌아갈 수 있는 걸 수 아래 화면에서 확인 할 수 있습니다.

-s 옵션에 HEAD 를 입력하여 commit hash(id)를 입력하지 않고도 가장 최신 지점으로 되돌아갈 수 있습니다.

git restore는 파일 내용 변경 뿐만 아니라 잘못된 git add를 취소 하는 기능도 가지고 있습니다.

git restore –staged [파일명]을 입력하면 잘못 스테이징된 파일을 unstage 할 수 있습니다.

관련 없는 파일들이 commit에 저장되지 않게 하는 겁니다.

Git revert 시나리오 : 고급 되돌리기 및 수정

특정 시점으로 돌아가 변경을 원할 시 유용합니다.

특히 공식적으로 변경 상황을 철회하고 수정을 진행하는 경우 사용하면 좋습니다.

revert 이후 commit에 무엇 때문에 철회를 하였고 수정을 하였다고 commit 메시지에 남기면 git history를 명시적으로 관리할 수 있게 되는 겁니다.

git revert를 사용하면 아래와 같은 메시지가 뜹니다.

여기서 내용을 추가 수정을 원한다면 추가 수정을 진행한 후에 commit을 진행합니다.

commit까지 완료해야 revert 과정이 완료되게 됩니다.

-n 옵션이 없다면 revert 이후 바로 commit을 진행하게 됩니다.

Git revert 과정에서 conflict 발생 시

git revert 과정에서 conflict가 발생하더라도 당황하지 마시고 충돌을 확인 후 진행 방향을 설정해 주시면 됩니다.

특정 시점의 변경사항만 되돌리기

commit1 -> commit2 -> commit3 -> commit4 와 같은 순서로 commit 지점이 존재한다고 가정해봅니다.

이때 commit1, 3, 4에 대한 기록은 유지한 채, commit2에 대한 부분만 되돌린다거나 수정해야 하는 경우도 발생할 수 있습니다.

이 경우에는 git revert commit2..commit3 명령어를 이용하면 됩니다.

Git reset : 완벽한 배수진 리셋

commit log를 날리기 때문에 (정확히는 HEAD를 댕기는 거지만…) 웬만하면 사용하지 않기를…

정말 commit log를 깔끔히 하고 싶은 경우, git reset --soft를 사용할 수 있지만 이런 경우는 git rebase를 사용할 수도 있습니다.

뭐 어떤 경우가 되었든 git reset은 사용하지 않기를 바라면서 일단 정리는 해봅니다.

git reset –soft

git reset –mixed

git reset –soft vs git reset –mixed

git reset –hard

git reset은 HEAD를 댕기는 거기 때문에 실제 git log에는 없는 commit id로도 다시 돌아갈 수는 있습니다.

마치며

git restore, git revert, git reset 만 정리하는 데도 시간이 반나절 이상 걸렸네요…ㅠㅜ

git rebase로도 git history를 수정할 수 있습니다. 하지만 git rebase는 단순히 되돌린다기 보다는 말 그대로 “새로운 지점”을 생성하기 위한 명령어에 가까운 것 같긴 합니다.

git을 특정 시점으로 되돌리는 3 가지 명령어를 정리 했지만 로컬 저장소가 아니라 원격 저장소에서 충돌이 일어난다면 git 되돌리기 혹은 수정 절차가 복잡해 질 것 같습니다.

저도 그런 경우는 많이 겪어 보지 못했지만 시간이 된다면 해당 내용도 차후에 정리해보면 좋을 것 같습니다.

참고하면 좋은 글

Leave a Comment

목차