Rebase와 merge는 내용보다 모양과 의도가 달라
둘 다 한 branch의 작업을 다른 branch에 통합하지만 이력에 남기는 모양이 달라. Merge는 parent가 둘인 새 commit으로 두 이력을 Y자에서 합쳐서 두 흐름을 graph에 보존해. Rebase는 source branch의 commit을 target tip 위에 새 commit으로 replay해 merge commit 없는 직선 chain을 만들어. 최종 내용은 같을 수 있어도 이력의 의미는 크게 달라.
결정 기준은 발산이 의미 있는지야. 장기 release branch를 합치거나 기능 완성을 작업 단위로 표시하고, 어디서 왔는지 audit trail을 보존하려면 merge해. 내가 feature를 만드는 동안 main도 움직였다는 우연한 발산이라면 rebase해. 짧은 feature branch마다 main을 merge하면 이력에 잡음이 쌓여. 날마다 ship하는 제품 팀에서는 rebase한 feature branch가 main을 기능의 단일 sequence로 읽히게 해.
팀 정책은 셋 가운데 하나를 고를 수 있어. (a) 모든 PR을 main 위에 rebase하고 fast-forward merge해 직선 이력을 만들기, (b) fast-forward할 수 있어도 --no-ff merge commit을 만들어 feature 단위를 남기기, (c) PR의 commit을 merge 때 하나로 squash해 main을 단순하게 만들기야. 셋 다 일관되게 쓰면 말이 돼. 뒤섞는 것이 진짜 문제야.
feature branch에서 git rebase main을 실행하면 로컬 commit을 main의 현재 tip 위에 replay해. conflict가 나면 rebase가 멈추고 해결 뒤 git rebase --continue로 이어가. git rebase --onto <new-base> <old-base> <branch>는 branch의 base를 정밀하게 바꿔. 처음에 잘못된 곳에서 branch를 만들었을 때 유용해.