[git] 이전 commit으로 돌아가기

soft? hard?

Kwoncheol Shin
4 min readJan 10, 2019
photo by Michael Aji Pradipta on Flickr

Git에서 이전 커밋으로 돌아가는 대표적인 방법은 reset 명령어를 사용하는 것이다. 아래와 같이.

$ git reset

그런데 위 명령어를 실행하면 아무 일도 일어나지 않는다. 어디로 reset을 시킬 것인지를 명시하지 않았기 때문이다. 이 글에서는 어디로 reset 시킬지를 표현하는 방법 두 가지를 알아볼 것이다.

예시를 위해 아래 commit history를 사용할 것이다.

commit 9190a3ac (HEAD)
commit 32edd1ed
commit 7f4d2367
commit b61f5f6e

Soft? Hard?

들어가기 전에 먼저 주의사항부터 이야기 하고싶다. reset에는 세 가지 종류가 있다. 예를 들어 설명하기 위해 우리가 하나 이전의 commit으로 reset한다고 가정해보자.

9190a3ac 에서 32edd1ed 으로 돌아간 것이다.

commit 9190a3ac
commit 32edd1ed (HEAD)
commit 7f4d2367
commit b61f5f6e

그냥 reset

그냥 reset을 이용한 경우, reset으로 돌아온 커밋 이후의 변경사항은 모두 unstaged 영역에 남는다. 위 예제에서는 9190a3ac 에서 변경했던 코드들이 현재 unstaged 영역에 남아 있게된다.

여기서 git add , git commit 을 해주면 다시 기존 상태로 돌아오게 된다. 아래와 같이 아무 옵션도 주어지지 않았다면 그냥 reset이 수행된다.

$ git reset {어디로 돌아갈지}

soft reset

그냥 reset이 변경사항을 unstaged 영역에 남겼다면, soft reset은 staged 영역에 남긴다. 즉, 위 예제에서 soft reset으로 돌아갔었다면, git commit 을 했을 때 기존 상태로 돌아오게 된다. 아래와 같이 --soft 옵션을 주어 사용할 수 있다.

$ git reset --soft {어디로 돌아갈지}

hard reset ⚠️

타노스 리셋이다. 변경사항을 모두 제거한다. 위 예제에서 hard reset을 사용했다면, 9190a3ac 에서 있었던 변경사항은 로컬에서 모두 사라진다. (만약 9190a3ac 변경사항이 origin에도 올라가있지 않다면 그 코드는 영영 안녕이다.)

아래와 같이 --hard 옵션을 주어 사용할 수 있다.

$ git reset --hard {어디로 돌아갈지}

자 이제 어디로 가야할지를 이야기하는 방법 두 가지를 살펴보자.

“N번째 뒤 commit까지 가주세요"

첫 번째는 HEAD 키워드를 이용하는 방법이다. 현재 로컬 브랜치로부터 머지 않은 커밋으로 돌아가는 경우 HEAD 를 사용하는 것이 간편하다.

$ git reset HEAD~1

위 명령어는 현재 로컬 브랜치로부터 하나 뒤에 있는 커밋으로 돌아가라는 의미이다. HEAD~ 뒤에 붙여준 1 이 ‘하나 뒤에 있는’ 이라는 의미를 전달하는 것이다.

만약 두 개 뒤에 있는 commit으로 돌아간다면 git reset HEAD~2 가 될 것이다.

앞에서 배운 soft, hard 옵션과 결합해서 사용하면 다음과 같다.

# 그냥 reset
$ git reset HEAD~1
# soft
$ git reset --soft HEAD~1
# hard ️
$ git reset --hard HEAD~1

HEAD 는 git에서 현재 로컬 브랜치의 위치를 나타내는 키워드이다.

“(구체적으로) 여기까지 가주세요”

특정 commit으로 돌아가는 방법도 있다. 사용법은 비슷하다. git reset 뒤에 commit id를 붙여주면 된다.

$ git reset 32edd1ed

위 명령어는 현재 로컬브랜치가 무엇이었든 상관 없이 32edd1ed 커밋으로 돌아간다.

주의사항 ⚠️

주의할 점이 있다. 여러 개 전의 커밋으로 돌아가는 경우, 그리고 그냥 reset 혹은 soft reset 현재 로컬브랜치로부터 해당 브랜치 사이에 있는 모든 변경사항이 모두 합쳐진 채로 unstaged 혹은 staged 영역에 남는다.

commit 9190a3ac
commit 32edd1ed
commit 7f4d2367
commit b61f5f6e (HEAD)

만약 위와 같이 9190a3ac 에서 b61f5f6e 로 돌아갔을 때, soft reset 을 했다면 7f4d2367 ~ 9190a3ac 에 있었던 모든 변경사항이 현재 로컬 브랜치 변경사항에 합쳐져서 남아있게 된다는 것이다.

atomic한 커밋을 유지해야 한다면 이를 주의 해야한다.

만약 특정 commit에 변경사항을 추가하고 싶은 의도라면 reset보다는 rebase를 사용하는 것이 좋다.

--

--