“main에 merge했다가 revert된 기능을, 기존 커밋을 재사용하지 않고 새 커밋으로 다시 반영하고 싶은 상황”
즉, Git이 ‘이미 본 적 없는 새로운 변경사항’으로 인식하게 만들고 싶은 상황에 사용합니다.
Git에서 작업 내용을 main
브랜치에 merge한 뒤, 예상치 못한 버그나 오류로 인해 해당 내용을 되돌려야 하는 상황이 발생할 수 있습니다.
이때 사용할 수 있는 방법은 크게 두 가지입니다.
git reset
은 가장 간단하게 커밋을 되돌리는 방법입니다. 이 방법은 기존 커밋 자체를 삭제하기 때문에 커밋 로그가 깔끔하게 유지됩니다.
다만 협업 중에는 권장되지 않습니다. reset은 로컬에서 혼자 작업 중일 때에만 사용하는 것이 안전합니다. 이미 푸시된 커밋을 reset하게 되면 협업자와의 커밋 기록이 꼬일 수 있습니다.
git revert
는 기존 커밋을 되돌리는 새로운 커밋을 추가하는 방식입니다. 이전 기록은 남기면서도 코드 변경만 원상복구할 수 있어 협업 시에 많이 사용됩니다.
예를 들어 다음과 같은 시나리오를 살펴보겠습니다.
feat/1/edit-data
브랜치에서 작업한 뒤 main
브랜치로 PR을 올립니다.
코드 리뷰와 테스트를 마친 후 merge를 진행합니다.
그런데 merge 이후, 문제가 생겨서, 다시 코드를 되돌려야 하는 상황이 생겼습니다.
이를 해결하기 위해, 작성자는 main
브랜치를 merge
이전 상태로 Revert PR을 만들어 되돌립니다.
이후 문제를 해결한 뒤, 기존 브랜치(feat/1/edit-data
)로 다시 PR을 올립니다.
하지만 실제 작업 내용에는 C, D의 작업 내용이 누락되었습니다.
PR에는 수정한 Commit만 포함되고, 기존에 작업했던 주요 변경사항(C, D 커밋 등)은 누락되어 있었습니다.
이 현상은 Git의 Revert 방식 때문입니다.
git revert
는 기존 커밋을 "삭제하는 새로운 커밋"을 생성합니다.
기존 커밋(C, D)은 여전히 Git의 이력에 존재하기 때문에, Git은 해당 변경사항이 이미 반영된 적이 있다고 인식해서, 새로운 PR에서 해당 커밋이 다시 반영되지 않습니다.
이로 인해, 이후에 merge를 하더라도 C, D 커밋의 내용은 누락된 채 main에 합쳐질 수 있습니다. 결과적으로 기존 작업이 사라지는 심각한 문제로 이어질 수 있습니다.
이런 상황에서 문제를 해결하려면 기존 브랜치를 그대로 재사용하지 말고, 새로운 브랜치를 만들어야 합니다.
그렇다고 해서 기존 작업을 처음부터 다시 작성할 필요는 없습니다.
이전 작업 커밋(C, D 등)은 그대로 사용하고, Git이 새로운 변경사항으로 인식하게 만드는 방법이 있습니다.
git cherry-pick
은 특정 커밋을 선택해서 현재 브랜치에 새로운 커밋으로 복사해주는 기능입니다. 이를 통해 Git은 "새로운 커밋으로 작업이 다시 들어왔다"고 인식하게 됩니다.
즉, 이전 작업 내용을 복사해서 새 브랜치에 적용하고, 그 위에 수정한 커밋도 추가한 후 PR을 다시 올리면 됩니다.
최종적으로 Merge하면 다음과 같은 커밋 흐름이 만들어집니다:
revert
는 기존 커밋을 없애는 게 아니라 "되돌리는 커밋"을 추가하는 방식입니다. 이로 인해 Git은 이전 커밋을 여전히 "이미 반영된 것"으로 인식합니다.
이 문제를 해결하기 위해서는
1. Revert된 브랜치를 그대로 재사용해서는 안 됩니다.
2. 새로운 브랜치에서 cherry-pick
을 활용해 기존 작업을 새로운 커밋으로 복사한 뒤 다시 PR을 올리는 방식으로 해결해야 합니다.