git rebase와 merge, 히스토리가 완전히 다르게 남는 이유
문제 발생
팀원이 이미 push한 공유 브랜치에 git rebase를 했다가, 다른 팀원의 로컬 브랜치와 히스토리가 완전히 어긋나 강제 push 충돌이 반복되는 문제가 발생했습니다.
원인 분석
git merge는 두 브랜치의 히스토리를 그대로 유지한 채 새로운 머지 커밋을 하나 만들어 두 갈래를 합칩니다. 기존 커밋의 해시는 전혀 바뀌지 않습니다.
git rebase는 다릅니다. 현재 브랜치의 커밋들을 대상 브랜치의 최신 커밋 위로 하나씩 다시 적용합니다. 이 과정에서 커밋의 부모가 바뀌므로 커밋 해시가 전부 새로 계산됩니다 — 내용은 같아 보여도 Git 입장에서는 완전히 다른 커밋입니다.
문제는 이미 다른 사람이 pull해서 로컬에 갖고 있는 커밋을 rebase로 다시 쓰면, 그 사람의 로컬 히스토리는 옛날 해시를 그대로 갖고 있고 원격은 새 해시로 바뀌어 있는 상태가 됩니다. 그 사람이 pull하면 Git은 두 히스토리를 별개로 취급해 merge 충돌이나 중복 커밋이 발생합니다.
해결 방안
- 이미 공유(push)된 브랜치는 rebase하지 않습니다. 이것이 가장 중요한 원칙입니다 — "Do not rebase commits that exist outside your repository"는 Git 공식 문서에도 명시된 경고입니다.
- rebase는 아직 push하지 않은 로컬 커밋을 정리할 때만 씁니다 — 예를 들어 기능 브랜치에서 작업하며 지저분해진 커밋들을 push 전에
git rebase -i로 정리(squash, reorder)하는 용도입니다. - 공유 브랜치를 최신 상태로 맞추고 싶다면 rebase 대신 merge를 쓰거나, 각 팀의 컨벤션에 따라 "기능 브랜치는 자유롭게 rebase, main/develop 같은 공유 브랜치는 절대 rebase 금지"처럼 명확한 기준을 정합니다.
- 실수로 이미 push한 커밋을 rebase했다면, 다른 협업자들에게 즉시 알리고 그들이
git pull --rebase나 브랜치를 새로 받도록 안내해야 합니다 — 조용히git push --force만 하면 다른 사람의 작업이 꼬이거나 유실될 수 있습니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.