아차스러운 실수로 커밋을 해버렸을 때 이전 커밋으로 돌리는 방법은 git reset과 git revert가 있습니다. 두 가지 작업을 비교해보고 어떠한 경우에 각 reset과 revert를 써야하는지 알아봅니다.
reset, revert의 차이
동일한 점은 둘 다 이전 커밋으로 되돌린다는 것인데, GitHub의 원격 저장소에 올라가 다른 사람과 코드 공유의 유무에 따라서 사용 방법이 달라집니다.
reset
커밋이 로컬에서 이루어졌다면, reset을 쓸 수 있습니다. 사용 방법은 git reset --option 돌아갈 커밋입니다.
아래는 예시입니다.
1. commit을 여러번 합니다.
git commit -m "first commit"
git commit -m "second commit"
git commit -m "third commit"
2. commit을 바로 이전으로 돌립니다.
git reset HEAD^
3. 여러개의 commit 이전으로 돌리는 경우
git reset HEAD~2
- first commit 커밋으로 돌아갑니다.
- HEAD~2 에 커밋의 해시를 써도 됩니다.
reset 옵션
--hard
- hard 옵션을 사용한다면 돌아간 커밋 이후의 변경 이력은 모두 삭제됩니다.
git commit -m "first commit"
git commit -m "second commit"
git commit -m "third commit"
git reset --hard [first commit hash]
git push
- 즉, 위처럼 실행할 경우에 second commit, third commit의 반영 내용은 모두 사라집니다. 이 상태에서는 코드도 함께 날아갑니다.
--mixed
- 변경 이력은 모두 삭제하지만 변경 내용은 남아있습니다.
git commit -m "first commit"
git commit -m "second commit"
git commit -m "third commit"
git reset --mixed [first commit hash]
git add .
git commit -m "~"
git push
- 위와 같이 실행한 경우에는 이력을 날아가나 unstage 상태로 코드는 남아있습니다. 코드를 반영하려면 add 명령어로 stage에 올리고 commit 합니다.
--soft
- 변경 이력은 모두 삭제하지만 변경 내용은 남아있습니다. 하지만 stage는 된 상태입니다.
git commit -m "first commit"
git commit -m "second commit"
git commit -m "third commit"
git reset --soft [first commit hash]
git commit -m "~"
git push
- add 명령어 없이 바로 commit이 가능합니다.
원격환경에 올린 상태에서 reset을 하고 push를 한다면?
- 로컬은 원격환경에 있는 commit을 삭제하고 원격에 덮으려고 하면 에러가 납니다.
- 이럴 경우 --force 옵션을 주어 강제로 로컬의 commit history를 원격 commit history로 덮어씁니다. 만약, 해당 리포지토리를 다른 개발자들과 공유하고 있다면 곤란한 상황에 놓일 수 있습니다.
reset을 사용하는 경우
위처럼 다른 개발자들과 코드가 공유될 경우에 reset을 사용하면 이전의 커밋 내용이 덮어지게 되므로 reset을 사용하는 경우는 아래와 같습니다.
- 혼자만 사용하는 브랜치인 경우
- 원격환경에 있지만 개인이 사용하는 브랜치인 경우
이외의 경우에는 commit을 되돌릴 때 revert를 사용합니다.
revert
revert는 reset과는 다르게 커밋을 삭제하는 것이 아닌 커밋을 추가하는 것 입니다. 하지만 이전 커밋과 정반대의 데이터를 추가하는 방식으로 코드를 되돌립니다. revert 명령어는 reset --soft, mixed와 동일한 결과를 가져오지만 이력에는 Revert "..." 라는 메세지가 추가됩니다.
git commit -m "first commit"
git commit -m "second commit"
git commit -m "third commit"
git revert [first commit hash]
위의 명령어를 실행하면 first commit 이후의 커밋들이 삭제되는 것이 아닌, first commit에 해당하는 내용만 삭제됩니다. 그리고 Revert "first commit" 이라는 커밋에는 first commit이 삭제된 이력이 남게 됩니다.
바로 커밋되게 하지 않으려면?
만약 revert한 결과를 stage 상태만 유지하고 commit를 하지 않으려면 --no-commit 옵션을 추가합니다.
git revert --no-commit [commit hash]
// After
git commit -m "Why revert which commit?"
git push
여러개의 커밋을 되돌리려면?
git revert [commit hash]...[commit hash]
git log에는
git revert [first commit hash]...[second commit hash]
git log
Revert "second commit hash"
Revert "first commit hash"
revert는 되돌리는 커밋이 중간에 있을 때 commit hash를 넣어 중간 커밋만 삭제할 수도 있고, 어떤 commit이 왜 revert 되었는 지 commit message를 통해 관찰 가능함으로 더욱 유용합니다. 또는 revert는 커밋이 삭제되는 것보다 이전으로 되돌리는 이력을 남김으로 history 유지 차원에서 더 좋은 선택입니다.
▽ 출처
'Error Log' 카테고리의 다른 글
서버 통신 헤더를 이용한 웹 보안 대응 (0) | 2022.06.16 |
---|---|
[Git Error] error: src refspec master does not match any 에러 (0) | 2021.07.26 |
[인텔리제이] Error: Exception thrown by the agent : java.rmi.server.ExportException: Port already in use: 1099; (0) | 2021.07.05 |