[Git/Github] Git 심화 명령어1 — revert(변경사항 되돌리기)

dEpayse
dEpayse_publication
7 min readAug 6, 2022

이번 포스트에서는 Git 의 기본 명령어가 아닌 Git 을 좀 더 내 입맛에 따라 사용할 수 있게 해주는 심화 명령어에 대해서 다뤄보기 시작하려고 한다.

심화 명령어으로 분류한 기준이 난이도 아니다. 기본 명령어 포스트에서는 Git 로컬 저장소에서 파일의 상태나, Stage, branch 등의 개념을 이해하면서 읽어야했기에 오히려 기본 명령어 포스트를 읽는데 더 많은 시간을 투자해야할 수 있다. 심화 명령어는 Git 을 더 내 입맛에 따라 다룰 수 있는 방법에 대해 다루는 것이라는 것을 알리며 revert 명령어에 대해 알아보자.

지난 포스트에서 reset 명령어에 대해서 다루었다. reset 은 이전의 내용으로 돌린다. revert 도 이전의 내용으로 돌아가는 것이다. 그럼 reset 과 revert 의 다른 점은 무엇일까? revert 에 대해 다룬 후, reset 과 비교해보자.

revert

revert 의 사전적 의미는 ‘되돌아가다' 라는 뜻이다. revert 는 특정 커밋, 또는 특정 커밋들을 새로운 커밋에서 되돌리는 역할을 한다. 즉, 변경 사항을 취소하는 것을 새로운 커밋에 기록하는 것이다.

reset 과의 차이점

Fig1. reset 과 revert 의 차이점 요약

revert 와 reset 의 큰 차이점 중 하나는 기록에 있다고 생각한다. reset 을 하고 git 을 계속 사용했다면, 언제 내가 그 변경사항을 취소했는지, 알 방법이 없다. 그러나 revert 를 사용한다면 어떤 실수를 해서 어떤 변경사항을 되돌렸는지 기록할 수 있다는 장점이 있다.

또 하나의 큰 차이점은 revert 는 특정 커밋의 변경사항만을 취소할 수 있다는 것이다. reset 은 브랜치 팁이 변경되기 때문에 단방향 흐름의 커밋에서 세 단계 전의 변경사항을 취소하고 싶을 때 한 단계, 두 단계 전의 변경사항도 같이 취소되지만, revert 는 특정 커밋의 변경사항만을 취소할 수 있다.

  • ‘git revert <커밋 id>’ : 특정 커밋 이력을 취소하는 커밋을 생성한다.
  • ‘git revert <커밋 id1> <커밋 id2>’ : 특정 커밋 이력들을 취소하는 커밋을 생성한다. 물론 3개 이상의 커밋도 가능하다.
  • ‘git revert <커밋 id1>..<커밋 id2> : [커밋 id1] 에서 [커밋 id2] 까지의 이력들을 취소하는 커밋을 생성한다.

revert 이후 conflict

revert 가 특정 커밋의 변경사항을 취소할 수 있지만, 그 때문에 충돌이 발생할 수도 있다.

Fig2. git revert conflict

Fig2 의 예시를 보면 319df 커밋에서도 ‘text.txt’ 파일의 첫 번째 줄을 수정했고, 그 다음 커밋인 c2b9e 커밋에서도 ‘text.txt’ 파일의 첫 번째 줄을 수정했다. 그런데 만약 이 중 하나의 커밋인 319df 커밋을 revert 하려고 하면 충돌이 발생한다.

이유는 git 이 319df 의 커밋을 되돌리려고 text.txt 파일을 319df 이전의 내용으로 수정하여 커밋을 생성하려고 했지만, 319df 이후의 c2b9e 커밋에서 같은 부분을 수정했기 때문에 충돌이 발생한 것이다.즉, c2b9e 의 커밋을 revert 한다면 충돌이 발생하지 않는다.

conflict 를 해결하는 방법은 지난 merge 포스트에서도 살펴봤기 때문에 본 포스트에서는 자세하게 다루지는 않는다. 해결하는 방법은 해당 파일의 충돌 부분을 수정하고 git add 를 통해 stage 에 올린 후 진행하면 된다. 만약 revert commit 이 생성되지 않은 상태에서 취소하고 싶다면, --abort 를 사용하여 revert 명령을 취소할 수 있다.

  • 충돌 발생시 충돌 해결 후 ‘git add <충돌 파일명>’ , ‘git revert continue’ 로 revert 를 완료할 수 있다.
  • ‘git revert --abort’ : revert 명령어 이후 revert commit 이 생성되지 않은 상태에서는 revert 를 취소할 수 있다.

merge commit revert

한 브랜치에 다른 브랜치의 변경사항을 적용하여 생긴 merge commit 의 경우 revert 하면 브랜치의 커밋으로 돌아가야 하는지 명시해주어야 한다. 이 때 ‘--mainline’ (‘-m’)이라는 옵션을 사용한다.

(git 에서 명령어의 옵션을 사용할 때 ‘--<옵션명>’을 사용한다. 그러나 하나의 대시만 있는 경우, 이 옵션을 줄여서 간단하게 쓰겠다는 의미이다.)

  • git revert -m <parent-number> : merge commit 을 revert 한 후 parent-number 브랜치의 커밋으로 돌아간 변경사항으로 적용한다.

여기서 parent-number 는 git log 로 revert 할 merge commit을 보면,

commit fea8e4b8d1c6f38228b58f7c75a6b9cc8651913e (HEAD -> master)
Merge: 1af4261 370a9bc
Author: author info
Date: some date

‘Merge : <커밋1 id> <커밋2 id>’ 부분을 볼 수 있는데, 왼쪽부터 parent-number 1번으로 시작하여 오른쪽 방향으로 1씩 증가한다. 즉 예시에서는 1af4261 이 parent-number 1번, 370a9bc 가 parent-number 2번이다.

fea8e4b 커밋을 revert 하고 1af4261 커밋으로 돌아가고 싶을 땐 다음과 같이 명령어를 작성할 수 있다.

git revert -m 1 fea8e4

유용한 revert options

  • --no-edit : git revert 를 사용하면 기본적으로 직접 커밋 메세지를 작성하도록 되어있지만, 커밋 메세지 변경 없이 기본 템플릿으로 커밋을 수행한다.
  • --no-commit (-n) : git revert 명령어 이후 충돌이 없을 경우 기본적으로 커밋을 생성하지만, 이 옵션을 사용하면 변경사항을 Working tree 에만 적용하여 stage에 올린다.

Reference

  1. [Git official — Book] — https://git-scm.com/book/en/v2
  2. [LainyZine: 프로그래머 가이드] “git revert 사용법: 이미 커밋한 내용을 되돌리는 방법” — https://www.lainyzine.com/ko/article/git-revert-reverting-commit-in-git-repository/
  3. [Level Up Coding] “Reverting a merge commit” — https://levelup.gitconnected.com/reverting-a-merge-commit-7de2e9114c7d

--

--

dEpayse
dEpayse_publication

나뿐만 아니라 다른 사람들도 이해할 수 있도록 작성하는, 친절한 블로그를 목표로.