Git - 특정 commit 삭제, 되돌리기 (reset, revert)

터미널에서 git 명령어로 특정 commit을 삭제하거나, 특정 commit으로 되돌아가는 방법을 소개합니다.

1. 특정 commit으로 되돌리기 (git reset)

git reset --hard <commit id> 명령어는 예전에 반영한 특정한 commit으로 되돌아가고, 그 이후에 반영한 commit들은 모두 제거하는 방법입니다.

예를 들어, 다음과 같이 3개의 commit이 반영되어있을 때, 최근에 반영한 두개의 commit을 제거하고 첫번째 commit인 ecb42ee로 되돌아가고 싶을 때는

$ git log
commit 1edf17e135a8b4e2996b1cba8eec8d5635469bdd (HEAD -> master)
Author: farfs <farfs.dev@gmail.com>
Date:   Sun Sep 18 15:32:37 2022 +0900

    Add c.txt

commit 5b85a825bff96da466af7dcf21e5a1edb2d96e97
Author: farfs <farfs.dev@gmail.com>
Date:   Sun Sep 18 15:32:23 2022 +0900

    Add b.txt

commit ecb42ee4da1d63caec1282b006b687ee1a74f46f
Author: farfs <farfs.dev@gmail.com>
Date:   Sun Sep 18 15:32:15 2022 +0900

    Add a.txt

다음과 같이 git reset --hard <commit id> 명령어를 사용할 수 있습니다.

$ git reset --hard ecb42ee4da1d63caec1282b006b687ee1a74f46f
HEAD is now at ecb42ee Add a.txt

명령어 입력 후, git log를 입력해보면 가장 최신 commit(HEAD)이 ecb42ee로 되어있습니다. 즉, ecb42ee 이후에 반영된 commit들은 모두 제거되었습니다.

$ git log
commit ecb42ee4da1d63caec1282b006b687ee1a74f46f (HEAD -> master)
Author: farfs <farfs.dev@gmail.com>
Date:   Sun Sep 18 15:32:15 2022 +0900

    Add a.txt

위의 reset 명령어는 아래와 같이 간단히 입력할 수도 있습니다. 참고로, HEAD는 가장 최근 commit을 가리키며, HEAD~1은 가장 최근 commit의 1개 전 commit을 의미하며 HEAD~2는 2개 전 commit인 ecb42ee를 의미합니다.

$ git reset --hard HEAD~2
HEAD is now at ecb42ee Add a.txt

마지막으로, 변경된 내용을 remote branch에 적용할 때는 충돌이 발생할 수 있으니 -f를 사용하여 강제로 업데이트시켜야 합니다.

$ git push -f origin <branch name>

1.2 commit을 삭제하지 않고, 변경사항을 staged 영역으로 되돌리기

git reset --soft <commit id> 명령어를 사용하면, --hard와 동일하게 commit id로 이동합니다.

두개의 차이점은, --hard는 특정 commit 이후에 적용한 commit들은 모두 삭제하는데 --soft의 경우, 수정사항들을 Staging 영역으로 되돌려서, 수정 후 다시 commit을 적용할 수 있습니다.

$ git reset --soft ecb42ee4da1d63caec1282b006b687ee1a74f46f

$ git log
commit ecb42ee4da1d63caec1282b006b687ee1a74f46f (HEAD -> master)
Author: farfs <farfs.dev@gmail.com>
Date:   Sun Sep 18 15:32:15 2022 +0900

    Add a.txt

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   b.txt
	new file:   c.txt

위와 같이 staged 영역으로 변경사항이 있을 때, 일부 내용을 수정하고 다시 commit을 적용할 수 있습니다.

$ git commit -m "Add b, c files"
[master 95ecebc] Add b, c files
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b.txt
 create mode 100644 c.txt

$ git log
commit 95ecebc740368ec9f2340b6794cd1b75f52184bf (HEAD -> master)
Author: farfs <farfs.dev@gmail.com>
Date:   Sun Sep 18 15:54:13 2022 +0900

    Add b, c files

commit ecb42ee4da1d63caec1282b006b687ee1a74f46f
Author: farfs <farfs.dev@gmail.com>
Date:   Sun Sep 18 15:32:15 2022 +0900

    Add a.txt

2. 특정 commit의 변경사항 제거 및 commit 등록 (git revert)

특정 commit의 변경사항을 모두 제거하고, 제거한 내용을 commit으로 등록하는 방법입니다. 보통 revert라고 합니다.

예를 들어, 위에서 소개한 project에서 아래와 같이 첫번째 commit ecb42ee를 revert하면, 현재 코드에서 이 수정사항만 제거가 됩니다.

$ git revert ecb42ee4da1d63caec1282b006b687ee1a74f46f
Removing a.txt
[master 6581856] Revert "Add a.txt"
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 a.txt

git log로 히스토리를 확인해보면 Revert "Add a.txt"라는 이름으로, 첫번째 commit의 수정사항을 제거하는 새로운 commit이 등록되었습니다.

$ git log
commit 65818566596380b0c888e9b840c5d61120bf72b9 (HEAD -> master)
Author: farfs <farfs.dev@gmail.com>
Date:   Sun Sep 18 15:55:56 2022 +0900

    Revert "Add a.txt"

    This reverts commit ecb42ee4da1d63caec1282b006b687ee1a74f46f.

commit 1edf17e135a8b4e2996b1cba8eec8d5635469bdd
Author: farfs <farfs.dev@gmail.com>
Date:   Sun Sep 18 15:32:37 2022 +0900

    Add c.txt

commit 5b85a825bff96da466af7dcf21e5a1edb2d96e97
Author: farfs <farfs.dev@gmail.com>
Date:   Sun Sep 18 15:32:23 2022 +0900

    Add b.txt

commit ecb42ee4da1d63caec1282b006b687ee1a74f46f
Author: farfs <farfs.dev@gmail.com>
Date:   Sun Sep 18 15:32:15 2022 +0900

    Add a.txt

reset과 revert의 차이점을 비교해보면, git reset은 예전 commit으로 돌아가면서 이후에 반영한 commit들을 깔끔히 제거했는데요.

git revert는 특정 commit의 변경사항을 제거하지만, 이전에 저장한 commit들은 삭제하지 않고 revert에 대한 새로운 commit을 추가합니다. 또한, revert를 사용한 경우, Remote branch와 충돌이 발생하지 않기 때문에 reset처럼 -f를 사용하여 push하지 않아도 됩니다.

관련 문서

Loading script...
codechachaCopyright ©2019 codechacha