본문 바로가기

programming

PR에 이미 병합된 커밋이 다시 나타남 (Bitbucket pull request 기존 커밋 포함)

부제: 브랜치 간 머지베이스 불일치로 인해 발생하는 중복 Merge 현상


🚩 발생한 문제

현재 메인으로 사용하는 브랜치는 두 가지입니다.

  • master: production 환경을 위한 소스
  • dev: dev 환경을 위한 소스

다음과 같은 순서로 작업을 진행하였습니다.

  1. feature/account-add 브랜치를 master에서 생성
  2. 작업 완료 후 commit (feature/int-script)
  3. feature/account-adddev 머지
  4. dev 환경 배포 후 정상 작동 확인
  5. release/0410 브랜치를 master에서 생성
  6. feature/account-addrelease/0410 머지 (master 배포 준비)
  7. release/0410master 머지 후 production 배포 정상 확인
  8. 새 작업을 위해 master에서 feature/address-edit 브랜치 생성
  9. 작업 완료 후 commit (feature/address-edit)
  10. feature/address-editdev 머지를 위한 PR 생성 시 이미 dev에 반영된 feature/account-add 변경내역이 Bitbucket PR 화면에서 함께 나타나는 문제 발생

 

즉, 예상되는 PR 변경점은 feature/address-edit 내용만 보여야 하는데, 이전에 이미 병합된 feature/account-add의 내용까지 PR에 포함된 것처럼 보였습니다.


🧑‍💻 원인 분석 및 설명

이 문제는 Git의 브랜치 간 merge-base 불일치 때문에 발생합니다.

  • feature/account-add 브랜치를 dev와 master 각각에 별도로 머지하면서, 같은 변경점이 서로 다른 커밋(SHA) 으로 생성되었습니다.
  • 이후 master에서 생성한 새 브랜치(feature/address-edit)를 dev에 머지할 때, Git은 두 브랜치 간의 공통 조상(commit) 을 기준으로 diff를 계산합니다.
  • 이때 dev가 이미 포함한 변경 내용임에도 master 브랜치에서의 변경점 SHA가 다르기 때문에, Git은 dev가 이미 가진 변경점을 "새로운 변경점"으로 간주하여 PR에 표시한 것입니다.

이를 시각적으로 표현하면 다음과 같습니다.

A───D1───dev
 \        ↑
  C1      | feature/account-add 내용 (SHA A)
   \
    \         (release/0410 경로)
     C1'──B───master──A1──feature/address-edit
            ↑
            | feature/account-add 내용 (SHA B)

여기서 dev는 SHA A의 변경점을, master는 SHA B의 변경점을 각각 가지고 있습니다. Git의 diff 계산 기준인 merge-base가 C1 이전의 커밋이므로 중복 변경이 발생한 것입니다.


✅ 해결 방법

이 문제를 해결하는 방법은 다음과 같이 크게 세 가지가 있습니다.

방법 1: dev 브랜치를 master로 최신화 (권장/선택)

git checkout dev
git merge --no-ff master  # 또는 rebase
git push origin dev
  • 장점: 한 번의 작업으로 이후 PR이 깔끔해집니다.
  • 단점: dev의 히스토리가 길어질 수 있습니다.
  • 선택한 방법은 배포할때 사용한 release 브랜치를 배포시 master 에도 merge 함과 동시에, dev 에도 merge 하는 방식으로 진행

방법 2: feature 브랜치를 dev 기준으로 rebase

git checkout feature/address-edit
git rebase dev  # 충돌 시 해결
git push -f origin feature/address-edit
  • 장점: PR이 간결해집니다.
  • 단점: force push가 필요합니다.

방법 3: dev에서 새 브랜치를 만들어 cherry-pick

git checkout dev
git checkout -b address-edit-v2
git cherry-pick <커밋SHA>...
git push origin address-edit-v2
  • 장점: force push가 필요 없고 가장 안전한 방법입니다.
  • 단점: 새 브랜치를 추가로 만들어야 합니다.

🚧 예방 방법

다음과 같은 방법으로 유사한 문제를 미리 방지할 수 있습니다.

  • 정기적으로 master 변경점을 dev에 반영합니다.
    • release 후 즉시 master의 변경사항을 dev 브랜치로 머지하거나 fast-forward 합니다.
  • CI/CD 파이프라인에서 merge-base 일관성을 체크합니다.
    • PR 생성 시 merge-base를 체크하는 스크립트를 추가하여 예방합니다.

이러한 현상을 이해하고 관리하면 더욱 명확하고 깔끔한 Git 브랜치 전략을 유지할 수 있을 것입니다.