단일 Protected Trunk-based 커스텀 브랜치 전략

Elli·2025년 12월 26일

오늘은 저희 팀과 본부에서 사용 중인 커스텀 브랜치 전략에 대해 소개하려고 합니다.

약 1년 9개월 전, 기존에 사용하던 브랜치 전략에 한계를 느끼면서
당시 같은 신입 팀원분들과 함께 문제를 정리하고, 시니어 개발자분들의 조언을 받아 설계한 전략입니다.

개인적으로는 지금까지도 상당히 만족하며 사용 중인 전략이어서,
비슷한 고민을 하고 계신 분들께 참고가 되었으면 하는 마음으로 정리해봅니다.

1. 기존 브랜치 전략

1.1. 과거 브랜치 전략

과거에 사용하던 브랜치 전략은 dev 브랜치가 모든 역할을 떠안는 구조였습니다.

  • 모든 feature / bugfix가 dev 브랜치로 바로 통합되었고
  • dev 브랜치가 개발·통합·배포 역할을 동시에 수행했으며
  • 릴리즈 일정도 명확하지 않아, 요청이 들어올 때마다 dev에서 바로 분기되었습니다

이것도 전략이라고 부를 수 있을까요

1.2. 어떤 문제가 있었냐면요

사업 일정에 따라 dev 브랜치는 완성도와 무관하게 stg로 강제 배포되거나 패키징되어야 했고,
그 과정에서 미완성 코드가 함께 배포되는 문제가 반복적으로 발생했습니다.

또한 릴리즈 시점마다 개발 중인 코드를 수동으로 주석 처리해야 했는데, 제가 개발한 부분이 아니면 어떤 부분을 주석처리 해야하는지도 명확하지 않았습니다.

2. 현재의 커스텀 브랜치 전략

2.1. TL; DR

문제를 해결하기 위해 새로운 전략을 고안했습니다.
이름을 붙여보자면 이렇습니다.

단일 Protected Trunk-based 브랜치 전략

신규 인력이 팀(또는 본부)에 합류하면, 저는 보통 이렇게 설명합니다.

  1. 이 전략의 주인공인 base 브랜치는 안전한 단일 trunk이며, 언제든지 배포·패키징이 되더라도 이상없는 안전한 코드들만 반영되어야 합니다. 반면 dev 브랜치는 배포된 개발환경과 연결된 브랜치이며, playground로 사용하고 있습니다.

  2. 모든 feature, bugfix, refactor 등은 base에서 따고, 해당 작업에 대해 개발한 당사자의 1차 검증이 완료되었을 때 PR을 통해 코드리뷰를 받고 base로 머지합니다.

    • 여기서 말하는 개발자의 1차 검증은 dev 브랜치로의 머지 및 dev 브랜치와 연결된 개발환경에서의 실제 동작 확인입니다. dev 브랜치로의 머지는 코드리뷰 없이 자유롭게 가능하고, dev -> base 로 소스가 흘러들어오지만 않도록 주의하면 됩니다.
  3. 그래도 어렵다면 두가지만 지켜주시면 됩니다.

    • 작업 브랜치에서 dev 브랜치를 pull 받는 건
      절대 금지 입니다. dev를 pull 받는 일은 거의 없습니다.
    • 개발자는 작업을 완료하면 머지를 두번 해야합니다. (dev로 먼저, 1차 검증 후 base로)

2.2. 자세히 설명하자면

2.2.1. 그림으로 이해하기

base는 항상 Single Source of Truth입니다.
보시다시피 릴리즈의 hotfix를 제외한 모든 변경 사항은 base에서 시작하며,
dev의 소스가 base로 직접 유입되는 일은 없습니다.

2.2.2. 의견 도출 과정

새 브랜치 전략을 설계하며 세운 조건은 명확했습니다.

⭐️ 1. 언제든지 패키징 될 수 있을 정도로 안정되면서, 기능 하나하나가 개발될 때마다 바로 반영할 수 있어야 하고,
2. PR을 자연스럽게 활성화 시킬 수 있는 방향이면 좋겠다.

초기에는 기존 전략을 유지한 채 PR만 규칙으로 강제하는 안도 검토했습니다.
이 방식은 새로운 전략 도입에 대한 거부감이 적고, 빠르게 적용할 수 있다는 장점이 있었습니다.

하지만 고민 끝에, 이 방식은 문제의 본질을 해결하지 못한다고 판단했습니다.
특히 1번 조건을 개발자 개인의 양심과 자율성에만 의존하는 구조는
지속 가능성 측면에서 불안 요소가 크다고 느꼈습니다.

그 결과,
base를 protected trunk로 명확히 분리하자는 결론에 도달했습니다.

이 전략은 다음과 같은 방식으로 두 조건을 모두 만족시킵니다.

  1. base에는 함부로 머지할 수 없기 때문에,
    안정적인 상태를 유지한 채 새로운 기능을 dev 환경에서 먼저 검증할 수 있습니다.

  2. feature → base PR은 개발 초기부터 열어둘 수 있어서
    충분한 코드 리뷰 시간을 확보할 수 있고
    base 머지는 1명 이상의 approve를 필수로 하여 최소한의 리뷰가 구조적으로 보장됩니다.

2.2.3. 자주 받는 질문들

Q1. 왜 base 와 배포된 브랜치 dev 굳이 분리했나요?

A1.
“로컬에서 충분히 검증된 코드를 dev에 올리면 되는 것 아닌가?”라는 질문을 자주 받습니다.
저희는 Micro Frontend Architecture 중 하나인 Webpack 5의 module federation 구조로 구성되어 있는데요, 하나의 host와 총 약 8-9개의 remote 모듈이 있습니다.
로컬 개발 시에는 모든 remote 서버를 동시에 띄우지 않기 때문에,
로컬에서는 정상 동작하던 코드가 실제 개발 환경에서는
remote 간 충돌로 인해 예상치 못한 이슈를 일으킨 경험이 여러 차례 있었습니다.

즉, local에서 동작한다고 해서 배포된 환경에서도 안전하다고 확신할 수 없는 구조였기 때문에
dev 환경에서의 실검증 단계를 분리할 필요가 있었습니다.

Q2. base에 배포된 환경이 없어서 불안하지는 않나요? 시간이 흐를수록 dev와 base의 소스가 점점 더 멀어질텐데요.

A2. 이 부분은 이번 전략을 고민하면서 가장 염려했던 지점입니다.

  • dev의 소스가 실수로 base에 병합될 가능성
  • 실험용 코드가 dev에만 누적되어 두 브랜치의 형상이 멀어질 가능성

이런 리스크를 고려해 base 전용 배포 환경도 검토했지만,
리소스 제약 이슈도 있고, base → tst 검증 브랜치에 이미 전용 검증 환경이 존재한다는 점을 고려해
필수 구성 요소는 아니라고 판단했습니다.

그럼에도 불구하고 안전장치를 하나 더 두기 위해,
dev와 base의 괴리가 일정 수준 이상 벌어졌다고 판단되면
기존 dev를 삭제하고 base 기준으로 dev를 재분기하는 운영 원칙을 두었습니다.

이를 통해 브랜치 간 괴리가 장기적으로 누적되는 상황을 방지하고자 했습니다.

Q3. 충돌이 빈번할 것 같은데 충돌은 어떻게 해결하나요?

A3. 하나의 기능에 대한 merge가 최소 두번(dev 로 n번, base로 1번) 이루어져야 하기 때문에 충돌이 상대적으로 꽤 빈번하게 발생합니다.

  • base 머지 시 충돌
    -> origin/base를 pull 받아 로컬에서 해결
  • dev 머지 시 충돌
    -> feature에서 dev를 pull 받는 것은 금지
    -> dev 기준의 충돌 해결용 브랜치를 따서 feature를 병합하거나 cherry-pick

2.3. 얻은 효과는요!

결국 궁극적 목표였던 안정성을 얻었습니다.
개발중에 갑자기 실제 사업 환경 배포 요청이 들어와도 더이상 불안하지 않습니다.
물론 base에 머지된 소스들이 버그가 없다! 는 전혀 아니지만, 크리티컬한 이슈가 없음은 확실하게 보장해줍니다.

또한 PR이 기능 개발 초기부터 열려 있기 때문에
완벽하지 않더라도 동료 개발자의 코드를 미리 보고 이야기하는 기회가 조금 더 많아졌습니다.

2.4. 그럼에도 한계점은!

장점 만큼이나 한계점도 명확합니다.

  1. 충돌 해결이 매우 귀찮습니다.

    • 그러나 기능 단위 아키텍쳐인 FSD(Feature Sliced Design)으로 프론트엔드 아키텍쳐를 개선한 이후로는, 각자 자신의 기능별로 slice를 나누어 개발하기 때문에 충돌 빈도가 확실히 줄었습니다.
  2. 두번 merge 하는 것이 귀찮습니다.

    • 귀찮음에서만 끝나면 다행인데, 가끔 까먹고 dev, base 둘 중 하나의 브랜치에만 merge 하는 경우도 종종 발생합니다. 이는 결국 개발자의 주의가 필요한 부분입니다.

3. 회고

3.1. 이 새로운 브랜치 전략에 만족하냐구요?

개인적으로는 정말 만족합니다.
분명 trade-off가 있지만... 안정성 에서 얻는 이점이 그 모든 불편함을 충분히 상쇄한다고 생각합니다.

약 15~20명의 프론트엔드 개발자가 하나의 모노레포에서 작업하는 현재의 환경에서 base 브랜치는 심리적인 안전장치로도 큰 역할을 하고 있습니다.

3.2. 어려웠던 점은

브랜치 전략을 수립할 당시는 지금보다 훨씬 신입이었습니다.

  • 브랜치 전략 변경에 대한 공감대를 형성하고
  • “왜 굳이 이렇게까지 해야 하느냐”는 질문에 합리적인 이유를 들어 답하는 것이
    조금 어려웠지만, 충분한 논의 끝에 대부분의 구성원이 전략의 필요성에 공감하게 되었습니다.

3.3. 배운 점

문제가 발생했을 때,
문제를 반복적으로 해결하는 방식이 아니라 문제 발생 자체를 구조적으로 예방하는 접근이 얼마나 중요한지 배울 수 있었습니다.

또, 동료 신입 개발자분들과의 지속적인 논의를 통해 더 나은 해결책을 만들어가는 경험이 즐거웠습니다.

4. 끝으로

이 브랜치 전략은 모든 팀에 적합한 만능 해법은 아닙니다.

  • 다인원이 하나의 레포에서 작업하고
  • 배포 안정성이 중요한 팀
    이라면 한 번쯤 참고해볼 만한 전략이라고 생각합니다.

더 나은 개선점이나 의견이 있다면 언제든지 이야기 나눠보고 싶습니다.

0개의 댓글