Study: DeveloperTools(DevTool)/DevTool: Git

[Git] reset과 revert 알고 사용하기

DrawingProcess 2022. 7. 20. 05:44
반응형

Git reset vs revert 차이점


  • 공통점: '과거로 되돌린다.' 는 것.
  • 차이점: '과거로 되돌리겠다는 내용도 기록되는가?(= commit 이력에 남는가?)' 이다.
  • reset : 시간을 아예 과거의 특정 사건(commit)으로 되돌립니다(= commit 이력이 남는가? X).
    • 아예 현재가 없었던 것 처럼 원하는 과거로 돌아갈 수 있습니다.
    • 정말 말 그대로 '리셋'이며, reset은 이력을 남기지 않습니다.
    • 따라서 현재까지의 commit 이력을 남기지 않고 원하는 시점으로 완전히 되돌아가고 싶을 때 사용할 수 있습니다.
  • revert : 현재에 있으면서 과거의 특정 사건(commit)들만 없던 일로 만듭니다(= commit 이력이 남는가? O).
    • 과거로 돌아가겠다는 이력을 남겨두고 원하는 시점으로 돌아갑니다.
    • 즉, 이전의 commit 내역을 남겨두고 새로운 commit을 생성하면서 과거로 돌아가게 됩니다.

 

Git reset vs revert 사용


git log: 되돌리고 싶은 시점 확인

$ git log --oneline
12741e5 (HEAD -> main) Add ThisIsaFile
d678197 Add .gitignore
97f1e31 Readme.md
  • 97f1e31 -> d678197 -> 12741e5 순으로 커밋한 것을 확인할 수 있습니다.
  • 이때, commit id: 97f1e31로 되돌리고 싶다면?

 

git reset: 커밋 취소하기

// git reset [option] <commit id>
$ git reset --hard 97f1e31
$  git log --oneline
d678197 (HEAD -> main) Add .gitignore
97f1e31 Readme.md
  • commit id
    • 기본적으로 git log에 나온 commit id를 적어서 사용합니다.
    • HEAD^: 가장 최근의 커밋이 취소됩니다.
    • HEAD~n: 현재로부터 n개의 커밋을 취소합니다.
  • option
    • --soft
      • commit된 파일들을 staging area로 돌려놓습니다. (commit 하기 전 상태로)
        • HEAD가 특정 커밋(과거 또는 미래)을 새롭게 가리키게 됩니다.
        • 대신 현재 작업 중인 working directory와 staging area는 아무런 영향을 받지 않습니다.
    • --mixed (default)
      • commit된 파일들을 working directory로 돌려놓습니다. (add 하기 전 상태로)
        • HEAD가 특정 커밋(과거 또는 미래)을 새롭게 가리키게 됩니다.
        • 그리고 staging area도 해당 커밋의 모습과 동일하게 변합니다.
        • 하지만 현재 작업 중인 working directory는 아무런 영향을 받지 않습니다.
    • --hard
      • commit된 파일들 중 tracked 파일들을 working directory에서 삭제합니다. (Untracked 파일은 여전히 Untracked로 남는다.)
        • HEAD가 특정 커밋(과거 또는 미래)을 새롭게 가리키게 됩니다.
        • 그리고 staging area와 현재 작업 중인 working directory도 해당 커밋의 모습과 동일하게 변합니다.
          • 추가로, 
      • 주의!!만약 현재 working directory에서 어떤 작업을 하다가 커밋을 하지 않고 --hard 옵션으로 git reset을 해버리면 이때까지 작업했던 게 다 날아가버리기에 주의할 필요가 있습니다.

+ git reset --hard: Untracked 파일 삭제하기

# 삭제 대상(Untracked files) 목록 확인
$ git clean -n

# Untracked files 파일 삭제
$ git clean -f
  • git reset --hard 옵션을 적용하면, commit된 파일들 중 tracked 파일들을 working directory에서 삭제합니다. 
    • 이때 Untracked 파일은 여전히 Untracked로 남게되는데, 이를 삭제하는 방법은 위와 같이 확인 후 삭제할 수 있습니다.

 

git revert: 커밋 내용 되돌리기

git revert 사용

$ git log --oneline
12741e5 (HEAD -> main) Add ThisIsaFile
d678197 Add .gitignore
97f1e31 Readme.md
$ git revert <commitId>

  • vscode 상에서 git revert를 사용하면, 다음과 같이 이전 커밋과 현재 커밋의 충돌점을 찾아주어 수정하도록 도와줍니다(merge conflict 해결시와 유사).
    • Accept Current Change: 초록부분에 해당하는 현재 코드를 그대로 사용합니다.
    • Accept Incomming Change: 파란부분에 해당하는 git revert하며 들어오는 코드로 변환합니다.
    • Accept Both Change: 두 commit: 일단 두 부분을 모두 남겨둡니다(이후 수정은 본인의 자유).

특정 커밋까지 git revert 사용

// 97f1e31까지 되돌리기 위한 현재부터 순차적으로 revert
$ git revert --no-edit 12741e5
$ git revert --no-edit d678197
$ git revert --no-edit 97f1e31

// 여러 커밋을 한꺼번에 되돌리는 방법
$ git revert --no-edit 12741e5 d678197 97f1e31
  • revert를 이용해서 특정 커밋으로 전으로 되돌리기 위해서는 순차적으로 revert해주어야 합니다.
    • 물론 특정 커밋만 되돌리기 위해서는 특정 커밋만 revert 해주면 됩니다.

+ git reset: 머지 커밋(Merge Commit)을 되돌리는 방법

$ git show 1123a41
commit 1123a419d52f8eea2273411b4afdfa1914e4195c (HEAD -> master)
Merge: 94668df 1bf9843
git revert -m 1 1123a41
git revert -m 2 1123a41
  • 1123a41 커밋은 94668df 커밋과 1bf9843 커밋을 머지한 커밋입니다.
  • 이를 되돌리기 위해서는 각각의 커밋으로 되돌려줘야 하며,
    • 94668df커밋으로 되돌리려면 -m 1, 1bf9843 커밋으로 되돌리려면 -m 2를 지정해주면 됩니다.
    • git show에서 보여지는 Merge: 94668df 1bf9843 값들에 차례대로 번호가 부여됩니다.

+ git format-patch & apply: 수동으로 revert하는 방법 (패치파일 생성 및 적용)

// 패치파일 생성: 커밋의 변경사항을 파일로 저장
$ git format-patch -1 12741e5
0001-Add-ThisIsaFile.patch

// 패치파일 확인
$ cat 0001-Add-d.patch

// 패치파일 적용
$ git apply -R 0001-Add-d.patch

++ 추가: git commit –amend: 커밋 덮어쓰기

$ git commit --amend
  • 보통 다음과 같은 상황에서 사용합니다.
    • 스테이징에 반영된 수정사항을 이전 커밋에 추가하고 싶거나,
    • 직전에 작성한 커밋 메시지를 수정하고 싶은 경우에 사용합니다.
    • 물론 위 두가지 모두에 해당되는 경우에도 사용할 수 있습니다.

 

결론


  • revert를 사용하면,
    • 중간에 무슨 문제가 있었는지, 왜 돌아갔는지 등의 기록이 가능하다는 장점이 있습니다.
    • 또한 다른 사람과 같은 브랜치에서 함께 작업할 때 코드 충돌을 최소화할 수 있습니다.
  • reset 을 사용하면,
    • 커밋 히스토리를 깔끔하게 유지할 수 있고, 혼자 작업할 때 편하게 되돌아갈 수 있다는 장점이 있습니다.
    • 그러나 타인과 같은 브랜치에서 함께 작업할 때 커밋이 뒤섞여버릴 수 있다는 위험한 단점이 있습니다.
  • 근데... 하나의 브렌치에서 여러 사람이 협업을 하는 경우가 있다면?(그럴리는 거의 없겠지만)
    • revertreset은 사용하지 않아야 합니다!

 

참고

반응형