- Published on
GitHub에서 실수로 PR을 승인했을 때 안전하게 되돌리는 방법
- Authors
- Name
- hongreat
- ✉️hongreat95@gmail.com
협업과정에서 Git을 사용한다면, Pull Request(PR)를 승인하고 병합(Merge) 하는 과정이 반드시 필요 합니다. 이번 글에서는 feature 브랜치라 하고(develop 과 1depth 차이인 작업브랜치)이를 예시로, develop 브랜치에 PR을 실수로 승인 처리 했을 때 깔끔하고 안전하게 되돌리는 과정을 기록합니다.
먼저, git log --oneline --graph --decorate
명령어를 사용하여 현재 상태를 확인합니다.
git log --oneline --graph --decorate
병합된 PR의 커밋과 develop
브랜치의 상태를 확인한 후, 실수로 병합된 PR의 커밋을 기록하거나 알아둡니다.
revert
를 사용하여 병합 되돌리기
1. revert
는 reset
과 달리, 병합된 커밋을 삭제하는 것이 아닙니다.
핵심은 새로운 커밋을 생성하고 변경 사항을 원상복구 한다 는 것입니다.
1.1 origin (최신) develop 브랜치를 가져옵니다.
git checkout develop
git pull origin develop
1.2 병합된 커밋을 revert 합니다.
병합 커밋을 되돌리기 위해 -m 1
옵션을 사용하여 revert합니다.
git revert -m 1 (최근 병합 커밋)
git revert 란?
git revert
는 특정 커밋의 변경 사항을 취소하는 새로운 커밋을 생성하는 명령어입니다.- 위에서 말했듯이 과거 상태로 단순히 "되돌리는" 것이 아닙니다. 취소된 변경 사항이 적용된 새로운 커밋이 추가됩니다.
즉!! git revert -m 1 (병합 커밋)
을 실행하면, develop 브랜치를 기준으로 병합된 feature 브랜치의 변경 사항을 취소하는 새로운 커밋이 생성됩니다.
-> 기존 상태를 덮어쓰지 않고, 취소된 결과를 유지한 채 히스토리를 남긴다.
develop
브랜치에 푸시합니다.
1.3 변경 사항을 git push origin develop
이렇게 하면 revert
된 커밋과 함께 origin 에 반영 되었을 것 입니다. 이제 origin develop
브랜치는 (이전에 작업해서 반영했을)feature
브랜치가 병합되기 전 상태로 복구되었습니다.
2. feature 브랜치를 다시 PR하기
revert
까지만 수행했다면, develop
브랜치에는 feature
브랜치의 기존 작업 사항이 없는 예전 상태로 돌아 갔을 것입니다. 이 파트는 feature
브랜치를 최신 develop
브랜치에 맞추고, 다시 PR을 보내는 과정을 통해 이전 작업을 복구하는 방법입니다.
2.1 feature 브랜치로 이동해줍니다.
git checkout feature-branch
2.2 최신 develop 반영
이 때 feature
브랜치의 변경 사항을 최신 반영하는데, rebase
를 사용합니다. 놓칠 수 있지만 핵심사실은 develop
의 revert
된 상태를 feature 브랜치에 반영하는 것입니다.
git pull origin develop
git rebase develop
merge
VS rebase
git merge or rebase develop 를 수행할 때 어떤 차이가 있을지 정리했습니다. 저는 가장 큰 차이를 주동/수동으로 커밋이 합쳐지는 것으로 생각합니다. 어떤 것이 더 좋은지는 상황에 따라 다르겠지만, rebase
를 사용하면 깔끔한 커밋 히스토리를 유지할 수 있습니다.
merge | rebase | |
---|---|---|
의미 | develop 브랜치의 변경 사항을 feature 에 병합 | feature 브랜치의 커밋을 develop 의 최신 상태 위로 다시 적용 |
히스토리 | 병합 커밋이 생성됨 (Merge commit ) | 커밋이 새로 만들어져 develop 위에서 다시 정렬됨 |
커밋 히스토리 | 병합 커밋이 추가되므로 (아주약간)복잡해짐 | 깔끔한 직렬 커밋 히스토리 유지 |
어떤 상황에서 사용되면 좋은지 | 공동 작업 시 변경 사항을 합칠 때 | feature 브랜치를 최신 상태로 유지할 때 |
풀어서 정리하면 다음과 같습니다.
git merge develop
은develop
브랜치의 변경 사항을feature
브랜치에 새로운 병합 커밋을 만들어 반영합니다.git rebase develop
은feature
브랜치의 커밋을 최신develop
브랜치 위에 다시 적용하여 깔끔한 히스토리를 유지합니다.이 과정들에서 충돌이 발생하면 당연히&반드시 해결하고 진행해야 합니다.
2.3 기존 feature 브랜치의 작업을 다시 적용합니다.
잠깐 rebase와 merge를 알고왔다면, 기존 커밋을 한번 확인할 필요도 있습니다. 만약에 기존 작업이 사라진 것처럼 보이게 될 것 입니다. 이전 작업의 커밋주소를 확인해야하는데, 명령어로는 git reflog
를 사용하여 기존 커밋을 확인할 수 있습니다.
git reflog
로그에서 원래 feature 브랜치 커밋을 찾고, 이를 다시 적용합니다. 작업간의 크게 충돌이 날수도 있고 꼬일 수 있기 때문에, 먼저 작성해둔 커밋 순서대로 cherry-pick
을 사용하여 적용합니다.
git cherry-pick (작업의 첫 번째 커밋)
git cherry-pick (작업의 마지막 커밋)
git cherry-pick
을 사용했나.
왜 cherry-pick
을 사용하면 feature 브랜치에서 원하는 커밋만 선택해서 적용할 수 있습니다.rebase
를 수행하는 과정에서 충돌이 발생할 수 있습니다. 충돌이 많을 것 같다면 직접 필요한 커밋만cherry-pick
으로 선택하는 것이 더 유리합니다.- 다시 순서를 정리하면 다음과 같습니다.
- 작업의 첫 번째 커밋 → 가장 기본적인 변경 사항이 적용됨
- 작업의 마지막 커밋 → 추가된 기능 및 수정 사항이 반영됨
이렇게 하면 코드가 충돌 없이 자연스럽게 적용됩니다.
2.4 강제 푸시하여 변경 사항을 반영합니다.
정상적으로 feature
브랜치에 변경 사항을 적용했다면, 강제 푸시를 통해 변경 사항을 반영합니다.
git push --force origin feature-branch
2.5 GitHub에서 새로운 PR을 생성합니다.
이제 모든 처리는 끝이 났습니다. 해당 원복된 커밋(작업)을 합치고자 한다면 다시 GitHub이나 사용하는 툴에서 feature 브랜치로 새로운 PR을 만들면 됩니다.
3. 회고 및 요약
작업자 간에 협업을 할 때, PR을 승인하고 병합하는 과정은 필수적이고 이런 과정에서 실수가 발생할 수 있습니다. 예전에는 실수로 PR을 승인했을 때 어떻게 해야할지 몰라 당황했던 기억이 있습니다. 이번 주에 작업도중에 실수로 PR을 승인했을 때, 간만에 당황했는데 비슷한 일을 겪고 당황하실 분들을 위해 이 내용을 기록합니다.
바쁜 사람을 위해, 요약하면 다음과 같습니다.
- PR을 실수로 승인했을 경우
revert
를 이용해 안전하게 되돌립니다.(삭제X / 새로운 복구커밋 생성O)- 병합된 커밋을 직접 삭제하는 것보다
revert
방식이 안전합니다.
- 병합된 커밋을 직접 삭제하는 것보다
git rebase develop
을 수행하면 최신develop
브랜치의 변경 사항을 반영하면서 깔끔한 커밋 히스토리를 유지할 수 있습니다.- 필요하면
git cherry-pick
을 이용해 기존 커밋을 다시 적용합니다.