본문 바로가기
목차
utils/git and github

git revert : 특정 commit 취소하기.

by ds31x 2023. 12. 30.
728x90
반응형

https://velog.io/@poagg42/git-revert

revert : 특정 commit 취소하기.

revert: 되돌리다.
취소할 commit id를 입력받음.

 

git revert

git revert [취소할 commit id (hash value)]repository에 반영된 내용을 취소해야 하는 경우 사용됨.

  • 취소를 시키고 취소된 상태의 새로운 commit을 추가하는 방식임. : 취소되는 commit도 log에서 확인 가능함.
  • 이 부분이 아예 취소되는 commit를 log에서도 삭제해버리는 reset 과의 가장 큰 차이점임.
    • reset 은 되돌아갈 commit의 commit id(=hash value)를 인자로 넘겨줌.
    • revert 취소시킬 commit의 commit id를 인자로 넘겨줌.
  • remote repository로 공동작업자와 같이 작업하는 경우, reset이 아닌 revert로 commit을 취소 시켜야 함.

revert는 자동으로 commit이 이루어지는데, repository에서 특정 commit을 취소시키고 이전 상태로만 돌아가려면 (즉, commit만 하지 않으려면) 다음과 같이 --no-commit 옵션을 준다.

git revert --no-commit [취소할 commit id (hash value)]
  • 이 경우, revert 하고 나서 다른 수정을 하고 나서 commit를 할 수 있음.

revert와 conflict

git revert는 실제적으로 대상이 되는 commit을 취소시키는 반대 commit을 새로 생성함.

git reset과 달리 기록이 보존되므로 여러 개발자가 참여하는 협업 branch에서도 사용가능함.

단, revert로 취소하는 commit id 이후에 이루어진 commit id들이 있을 경우 conflict가 일어나기 매우 쉬움.

때문에 돌아가고자 하는 commit id 이후의 구간을 모조리 취소 시키는 것이 실무적으론 편하다.

git revert <복원고자 하는 commit ID>..<현재 commit ID>
  • A..BA 직후에 이루어진 commit부터 B까지를 의미함 (A 불포함)
  • A^..B 라면 A를 포함하여 B까지의 commit을 의미함 (A 포함): ^ (caret)parent commit을 의미하기 때문임.
  • ^ (caret) 은 Parent Reference로 Relative Refernce의 일종임.

2025.07.24 - [utils/git and github] - Relative Reference-Git-caret and tilde + Reflog Reference

 

Relative Reference-Git-caret and tilde + Reflog Reference

Git에서 commit을 가리킬 때 Absolute reference와 Relative reference, Reflog Reference 의 세가지 방식이 있음.Absolute reference: commit id를 사용함.Relative reference: tilde(~)와 caret(^)Reflog reference: at(@) 을 사용함.SHA1 으로

ds31x.tistory.com

 

만약 돌리고자 하는 commit id 가 2이고, commit id 2 직후에 이루어진 commit id가 3이면 다음과 같이 수행.

git revert <commit id 2>..HEAD

 


예제.

1. git_ex_revert 라는 directory를 만들고 해당 디렉토리 안에서 git init -b main을 수행한다.

git init -b main
git config user.email dsaint31@gmail.com
git config user.name "hkkim"

2024.05.20 - [utils/git and github] - [Git] init : local repository 생성.

 

[Git] init : local repository 생성.

git init기존 로컬 디렉토리를 Git repository(저장소)로 만들어주는 명령어.git init Local repository 를 생성하기 때문에remote repository 없이 처음 git 으로 버전 관리할 때 사용하는 명령어.실습mkdir first-gitcd

ds31x.tistory.com

 

2. test00.txt 파일을 해당 directory 내에 만들고 내용을 다음과 같이 함.

# 최초 내용.

이 파일은 revert로 돌아올 때 확인할 수 있는 file임.

 

3. git add test00.txt 를 통해 stage로 이동시키고, git commit -m "first commit" 를 수행하여 repository로 이동시킴.

 

4. test01.txt 파일을 추가하고 해당 파일의 내용은 다음과 같이 함.

# content

두번째 commit에 추가되는 파일임.

 

5. git add test01.txt 를 통해 stage로 이동시키고, git commit -m "second commit" 를 수행하여 repository로 이동시킴.

 

6. test01.txt 파일을 다음과 같이 새로운 내용을 추가하여 저장.

# content

두번째 commit에 추가되는 파일임.

# modified

세번째 commit에서 수정된 부분임.

 

7. git add . 를 통해 stage로 이동시키고, git commit -m "third commit" 를 수행하여 repository로 이동시킴.

 

8. git log를 수행하여 두번째 commit에 대한 commit id를 얻어온다 :

63fa392939de9ef2156c124f94340ff30189b993 라고 가정.

 

9. git revert 63fa392939de9ef2156c124f94340ff30189b993 를 수행한다.

 

9번을 수행하며 , CONFLICT가 발생한다. 메시지는 다음과 같다.

❯ git revert 63fa392
CONFLICT (modify/delete): test01.txt deleted in parent of 63fa392 (second commit) and modified in HEAD.  Version HEAD of test01.txt left in tree.
error: could not revert 63fa392... second commit
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git revert --continue".
hint: You can instead skip this commit with "git revert --skip".
hint: To abort and get back to the state before "git revert",
hint: run "git revert --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
❯
  • 앞서 revert로 두번째 commit을 취소하면,
    test01.txt가 없는 첫번째 commit으로 되돌려지고,
    되돌려진 상태에서 네번째 commmit이 이루어져야 한다.
  • 문제는 세번째 commit에서 test01.txt에 수정을 했는데,
    두번째 commit을 취소키기 위해 
    git은 test01.txt를 삭제하여 첫번째 commit와 동일한 상태로 네번째 commit을 하려고 시도함.
  • 이 시도는 해당 세번째 commit에서 해당 파일을 고친 내용과 충돌(conflict)이 됨.
  • 때문에 이를 해결(resolving conflicts)하고나서
    해결된 working tree를 stage로 올린(mark them with ...) 후에
    git revert --continue를 수행하라는 메시지가 뜨게 됨.

일반적으로 conflict가 발생하지 않는 경우엔 그냥 잘 되었다는 메시지가 뜨지만,
생각보다 revert의 경우 conflict가 자주 발생한다.
때문에 예제에서 conflict가 발생하도록 한 것임.


10. confilct 문제를 일으키는  test01.txtgit rm test01.txt로 삭제하고 이를 stage에 반영시켜 conflict를 해결한다.
11. 이 후 git revert --continue를 수행한다.

 

위의 예는 revert를 하는 간단한 예제이며, conflict를 해결하는 방법을 소개하고 있다.
제대로 수행하면 다음과 같은 메시지가 보임.

❯ git rm test01.txt
rm 'test01.txt'
❯ git revert --continue
[main 5794e6a] Revert "second commit"
 1 file changed, 7 deletions(-)
 delete mode 100644 test01.txt
  • 위에서 git revert --continue 를 수행하면 message를 입력하는 vim 화면이 열림. 
  • ESC 누르고 :wq 를 입력하면 기본 message로 로그가 기록됨.
  • 만약 여러 개의 commit을 revert하도록 범위로 설정한 경우엔 각각의 경우의 message 입력 vim화면이 열린다.

같이 보면 좋은 자료들

2025.07.24 - [utils/git and github] - Relative Reference-Git-caret and tilde + Reflog Reference

 

Relative Reference-Git-caret and tilde + Reflog Reference

Git에서 commit을 가리킬 때 Absolute reference와 Relative reference, Reflog Reference 의 세가지 방식이 있음.Absolute reference: commit id를 사용함.Relative reference: tilde(~)와 caret(^)Reflog reference: at(@) 을 사용함.SHA1 으로

ds31x.tistory.com

 

2024.05.20 - [utils/git and github] - [Git] Git Summary (작성중)

 

[Git] Git Summary (작성중)

git이란2024.05.20 - [utils/git and github] - Git : 소개 git 설치 후 해줘야 하는 작업들[Git] git 설치 후 우선 해줘야 하는 작업들 (tistory.com)local repository 초기화2024.05.20 - [utils/git and github] - [Git] init : local repo

ds31x.tistory.com

 

728x90