Git Flow
1. 개요
1. 개요
빈센트 드리센(Vincent Driessen)이 2010년 1월 5일에 제안한 Git 워크플로우 전략이다. 이는 소프트웨어 개발 프로젝트에서 릴리스 관리와 병렬 개발을 효율적으로 지원하기 위해 설계된 브랜칭 모델(Branching Model)이다.
Git Flow는 크게 메인 브랜치와 보조 브랜치로 구분되는 엄격한 브랜치 구조를 정의한다. 메인 브랜치에는 제품의 공식 배포 이력을 관리하는 master 브랜치와 다음 배포를 위한 통합 및 개발이 이루어지는 develop 브랜치가 있다. 보조 브랜치에는 새로운 기능 개발을 위한 feature 브랜치, 배포 전 최종 준비를 위한 release 브랜치, 그리고 운영 중 발생한 긴급 버그 수정을 위한 hotfix 브랜치가 있다.
이 전략은 각 브랜치의 역할과 생명주기를 명확히 규정하여, 특히 버전 관리가 중요한 대규모 프로젝트나 정기적인 소프트웨어 배포가 필요한 환경에서 구조적인 협업을 가능하게 한다. 개발자는 develop 브랜치에서 파생된 feature 브랜치에서 독립적으로 작업한 후, 다시 develop 브랜치로 병합(Merge)하는 방식으로 기능을 추가한다.
릴리스 준비 단계에서는 develop 브랜치에서 release 브랜치를 생성하여 테스트와 버그 수정을 진행한 후, 안정화된 버전을 master와 develop 브랜치에 동시에 병합한다. 운영 중인 master 브랜치에서 긴급한 결함이 발견되면 hotfix 브랜치를 생성하여 신속하게 수정하고 배포할 수 있다.
2. 브랜치 구조
2. 브랜치 구조
2.1. 메인 브랜치 (Main Branches)
2.1. 메인 브랜치 (Main Branches)
Git Flow에서 메인 브랜치는 프로젝트의 핵심적인 두 가지 브랜치로, 마스터 브랜치(master)와 개발 브랜치(develop)로 구성된다. 이 두 브랜치는 항상 존재하며, 프로젝트의 주요 이력을 담당한다.
마스터 브랜치는 프로덕션 환경에 배포 가능한 상태의 코드만을 유지하는 브랜치이다. 이 브랜치의 각 커밋(Commit)은 공식적인 릴리스를 의미하며, 태그를 통해 버전 정보를 관리한다. 따라서 마스터 브랜치의 코드는 항상 안정적이고 배포 준비가 완료된 상태여야 한다.
개발 브랜치는 다음 릴리스를 위한 모든 개발 작업이 통합되는 중심 브랜치 역할을 한다. 새로운 기능 개발(Feature)은 이 브랜치에서 분기된 피처 브랜치(Feature branch)에서 이루어지며, 완성된 기능은 다시 개발 브랜치로 병합(Merge)된다. 이 브랜치는 다음 배포를 위한 최신 개발 변경사항을 포함하므로, 항상 안정된 상태를 유지해야 하지만 완전한 프로덕션 수준의 안정성은 보장하지 않는다.
이 두 메인 브랜치를 분리함으로써, 개발 팀은 다음 릴리스를 위한 지속적인 개발 작업(개발 브랜치)과 현재 프로덕션 코드의 안정성 유지(마스터 브랜치)를 동시에 효과적으로 관리할 수 있다. 이 구조는 소프트웨어 개발 수명 주기(SDLC)에서 지속적 통합(Continuous Integration)과 릴리스 관리(Release Management)를 지원하는 기반이 된다.
2.2. 보조 브랜치 (Supporting Branches)
2.2. 보조 브랜치 (Supporting Branches)
Git Flow에서 보조 브랜치는 특정 목적을 위해 일시적으로 생성되고, 작업이 완료되면 병합 후 삭제되는 브랜치이다. 이들은 메인 브랜치인 master와 develop 브랜치를 중심으로 운영되며, 프로젝트의 다양한 개발 활동을 체계적으로 분리하고 관리하는 데 핵심적인 역할을 한다. 보조 브랜치는 크게 기능 브랜치, 릴리스 브랜치, 핫픽스 브랜치의 세 가지 유형으로 구분된다.
각 보조 브랜치는 명확한 생성 지점과 병합 대상, 그리고 생명주기를 가진다. 기능 브랜치는 새로운 기능을 개발할 때 develop 브랜치에서 분기하여 생성하며, 개발이 완료되면 다시 develop 브랜치로 병합된다. 릴리스 브랜치는 새로운 버전 출시를 준비하는 단계에서 develop 브랜치에서 분기하여 생성하고, 최종적으로 master 브랜치와 develop 브랜치 양쪽에 병합된다. 핫픽스 브랜치는 프로덕션 환경에서 발생한 긴급한 버그를 수정할 때 master 브랜치에서 분기하여 생성하며, 수정 완료 후 master와 develop 브랜치에 모두 병합된다.
이러한 구조는 개발, 테스트, 출시, 유지보수라는 서로 다른 개발 단계를 명확히 분리함으로써 프로젝트의 안정성을 유지하는 데 기여한다. 예를 들어, 다음 출시를 위한 기능 개발은 develop 브랜치에서 계속 진행되는 동시에, 현재 버전의 릴리스 준비나 긴급 수정은 별도의 브랜치에서 독립적으로 처리할 수 있다. 모든 보조 브랜치는 그 목적이 달성되면 삭제되어 브랜치 목록을 깔끔하게 유지하도록 설계되었다.
3. 작업 흐름
3. 작업 흐름
3.1. 기능 개발 (Feature)
3.1. 기능 개발 (Feature)
기능 개발은 Git Flow에서 새로운 기능을 추가하거나 기존 기능을 개선하는 작업을 위해 사용되는 보조 브랜치이다. 이 브랜치는 develop 브랜치에서 분기하여 생성되며, 기능 개발이 완료되면 다시 develop 브랜치로 병합된다. 이 과정은 소프트웨어 개발의 핵심 활동을 구성하며, 주로 feature/ 접두사를 붙여 브랜치 이름을 짓는다.
기능 개발 브랜치는 메인 브랜치인 master나 develop을 직접 건드리지 않고 독립적인 환경에서 작업할 수 있게 해준다. 개발자는 이 브랜치에서 코드를 작성하고, 커밋을 쌓아가며, 동료와의 코드 리뷰를 진행할 수 있다. 기능이 완성되고 테스트를 통과하면, 해당 feature 브랜치는 develop 브랜치로 병합 요청을 생성하거나 직접 병합하여 통합한다. 병합 후에는 해당 기능 브랜치를 삭제하는 것이 일반적인 관행이다.
이 방식의 장점은 개발 중인 기능이 안정성을 유지하는 develop 브랜치의 상태에 영향을 주지 않는다는 점이다. 여러 개발자가 동시에 서로 다른 기능을 개발할 때 특히 유용하며, 병렬 개발을 촉진한다. 또한, 특정 기능 개발이 중단되거나 변경되어도 해당 브랜치만 처리하면 되므로 프로젝트 관리가 용이해진다.
브랜치 유형 | 분기 출처 | 병합 대상 | 목적 |
|---|---|---|---|
|
|
| 새로운 기능 개발 또는 기존 기능 개선 |
3.2. 릴리스 준비 (Release)
3.2. 릴리스 준비 (Release)
릴리스 준비 브랜치는 develop 브랜치에서 분기하여 생성된다. 이 브랜치는 새로운 프로덕션 릴리스를 위한 최종 준비 단계를 담당한다. 여기서는 새로운 기능 추가는 중단하고, 버그 수정, 문서화 작업, 빌드 설정 조정 등 릴리스와 직접적으로 관련된 작업만 수행한다. 이 단계에서 발견된 모든 버그는 해당 릴리스 브랜치 내에서 직접 수정되며, 수정 사항은 develop 브랜치에도 병합되어 다음 릴리스에 반영되도록 한다.
릴리스 준비가 완료되어 QA 테스트를 통과하면, 해당 릴리스 브랜치는 master 브랜치로 병합된다. 이때 병합 커밋에는 시맨틱 버저닝 규칙에 따른 새로운 버전 태그(예: v1.0.0)가 부여된다. 동시에, 릴리스 기간 동안 이루어진 모든 변경 사항은 develop 브랜치에도 다시 병합되어, 릴리스 브랜치에서의 작업 내용이 개발 메인라인에 유실되지 않도록 한다. 작업이 완료된 릴리스 브랜치는 삭제된다.
이 과정을 통해 master 브랜치는 항상 안정적이고 배포 가능한 상태를 유지하며, CI/CD 파이프라인을 통한 자동화된 배포가 용이해진다. 또한, 릴리스 사이클의 마지막 단계를 명확히 구분함으로써 팀이 배포에 집중할 수 있는 기간을 제공한다.
3.3. 긴급 수정 (Hotfix)
3.3. 긴급 수정 (Hotfix)
긴급 수정(Hotfix) 브랜치는 프로덕션 환경의 master 브랜치에서 발견된 중요한 버그나 보안 취약점을 신속하게 해결하기 위해 사용된다. 이 브랜치는 릴리스 주기와 무관하게 즉시 생성되어야 하며, master 브랜치에서 직접 분기한다는 점이 특징이다. 릴리스 브랜치가 존재할 경우에도, 긴급 수정은 릴리스 브랜치가 아닌 master 브랜치에서 시작한다.
작업 흐름은 먼저 master 브랜치에서 hotfix- 접두사가 붙은 이름으로 새로운 Hotfix 브랜치를 생성하는 것으로 시작한다. 이 브랜치에서 버그를 수정한 후, 수정 사항은 master 브랜치와 develop 브랜치 양쪽으로 병합(Merge)되어야 한다. master 브랜치로의 병합은 즉시 새로운 패치 버전의 소프트웨어 릴리스를 태그로 표시하게 된다. 이 과정을 통해 프로덕션 코드가 최신 버그 수정 사항을 반영하도록 보장한다.
Hotfix 브랜치의 사용은 Git Flow가 애자일 개발보다는 예측 가능한 릴리스 주기를 가진 전통적인 소프트웨어 개발 수명주기에 더 적합한 이유 중 하나를 보여준다. 이는 공식 릴리스 사이에 발생하는 비상 사태에 대응할 수 있는 구조화된 채널을 제공한다. 작업이 완료되면 Hotfix 브랜치는 삭제되어 브랜치 목록을 깔끔하게 유지한다.
이 접근 방식의 장점은 프로덕션 이슈에 대한 신속한 대응이 가능하다는 점이다. 그러나 단점으로는, develop 브랜치로의 병합 과정에서 충돌(Conflict)이 발생할 수 있으며, 릴리스 브랜치와 별개로 진행되므로 두 브랜치 모두에 동일한 수정을 적용해야 하는 관리 부담이 있을 수 있다.
4. 장단점
4. 장단점
4.1. 장점
4.1. 장점
Git Flow는 명확한 브랜치 역할과 구조화된 워크플로우를 제공하여, 특히 규모가 크고 체계적인 릴리스 주기를 가진 프로젝트에서 여러 가지 장점을 가진다.
가장 큰 장점은 프로젝트의 다양한 개발 단계를 명확히 분리하여 관리할 수 있다는 점이다. 마스터 브랜치는 항상 배포 가능한 안정된 상태를 유지하고, 개발 브랜치는 다음 릴리스를 위한 통합 공간이 된다. 이로 인해 새로운 기능 개발이나 실험적인 작업이 진행 중이더라도 언제든지 안정된 버전의 코드를 배포할 수 있다. 또한 릴리스 브랜치와 핫픽스 브랜치를 통해 정기적인 출시 준비와 긴급한 버그 수정 작업이 서로 간섭 없이 독립적으로 수행될 수 있어 운영의 안정성을 높인다.
또한 이 전략은 팀 내 협업과 프로젝트 관리에 도움을 준다. 각 브랜치의 용도와 병합 규칙이 표준화되어 있어, 팀원들이 자신의 작업이 전체 프로젝트 흐름에서 어디에 위치하는지 쉽게 이해할 수 있다. 이는 신규 팀원의 온보딩을 용이하게 하고, 코드 리뷰와 테스트를 체계적으로 진행할 수 있는 틀을 마련해 준다. 특히 롤백이 필요한 상황에서도 마스터 브랜치의 이전 태그를 통해 쉽게 안정된 상태로 복귀할 수 있다.
결론적으로 Git Flow는 소프트웨어 개발 수명 주기의 각 단계를 시각화하고 표준화함으로써, 복잡한 프로젝트의 개발, 테스트, 출시, 유지보수 과정을 체계적으로 관리할 수 있는 견고한 프레임워크를 제공한다는 점이 주요 강점이다.
4.2. 단점
4.2. 단점
Git Flow는 구조화된 접근 방식으로 인해 복잡성이 증가한다는 단점이 있다. 브랜치 종류가 많고 각 브랜치 간의 병합 규칙이 엄격하여, 특히 소규모 팀이나 지속적 배포를 목표로 하는 프로젝트에서는 불필요한 오버헤드로 작용할 수 있다. 마스터 브랜치와 개발 브랜치를 장기간 유지하는 방식은 병합 충돌을 해결하는 데 상당한 시간을 소모하게 만들며, 기능 브랜치의 수명이 길어질수록 이 문제는 더욱 심화된다.
릴리스 주기가 비교적 길고 예측 가능한 전통적인 소프트웨어 개발 모델에 적합하게 설계되어, 현대적인 애자일 및 데브옵스 환경에서 요구되는 빠른 반복과 지속적 통합, 지속적 배포에는 잘 맞지 않을 수 있다. 릴리스 브랜치를 별도로 관리하는 과정 자체가 배포를 지연시키는 요인이 될 수 있으며, 핫픽스 브랜치의 사용은 예상치 못한 복잡성을 초래하기도 한다.
결과적으로, 이 전략은 학습 곡선이 가파르고 모든 팀원이 철저한 이해와 준수를 필요로 한다는 점에서 진입 장벽이 있다. 프로세스의 복잡성은 간단한 변경사항을 적용하는 데에도 여러 단계의 병합 작업을 요구할 수 있어, 전체적인 개발 속도를 저하시킬 위험이 있다. 이러한 이유로 많은 팀이 보다 단순하고 유연한 대안인 GitHub Flow나 트렁크 기반 개발을 선호하는 추세이다.
5. 대안 브랜칭 전략
5. 대안 브랜칭 전략
5.1. GitHub Flow
5.1. GitHub Flow
GitHub Flow는 GitHub에서 제안한 단순하고 가벼운 브랜치 전략이다. Git Flow가 복잡한 릴리스 주기와 병렬 개발을 위해 설계된 반면, GitHub Flow는 지속적 배포와 빠른 반복에 중점을 둔다. 이 전략은 마스터 브랜치를 항상 배포 가능한 상태로 유지하고, 모든 새로운 기능 개발이나 버그 수정은 이 마스터 브랜치에서 분기된 기능 브랜치에서 이루어진다.
핵심 원칙은 마스터 브랜치를 항상 안정적으로 유지하는 것이다. 따라서 개발자는 새로운 작업을 시작할 때 항상 마스터 브랜치에서 새로운 브랜치를 생성한다. 이 기능 브랜치에서 코드를 작성하고 커밋을 쌓은 후, 작업이 완료되면 풀 리퀘스트를 생성하여 동료들의 코드 리뷰를 요청한다. 풀 리퀘스트는 코드 변경에 대한 논의와 검토의 중심 장소가 된다.
코드 리뷰와 필요한 테스트를 통과한 후, 해당 기능 브랜치는 마스터 브랜치로 병합된다. GitHub Flow의 중요한 특징은 병합 직후 즉시 배포하는 것을 권장한다는 점이다. 이를 통해 변경 사항을 빠르게 프로덕션 환경에 적용하고 사용자 피드백을 즉시 받을 수 있다. 만약 배포 후 문제가 발견되면, 새로운 핫픽스 브랜치를 만들어 동일한 흐름으로 신속하게 대응한다.
이 전략은 애자일 개발 방식과 잘 어울리며, 특히 웹 애플리케이션 또는 서비스형 소프트웨어와 같이 자주 배포가 이루어지는 프로젝트에 적합하다. Git Flow에 비해 학습 곡선이 낮고, 브랜치 관리가 간단하여 소규모 팀이나 데브옵스 문화가 정착된 조직에서 선호되는 경향이 있다.
5.2. GitLab Flow
5.2. GitLab Flow
GitLab Flow는 GitLab이 제안한 브랜치 전략이다. 이 전략은 Git Flow의 복잡성을 줄이고 지속적 배포 및 지속적 통합 환경에 더 적합하도록 설계되었다. GitLab Flow는 프로덕션 환경을 중심으로 한 단순한 브랜치 구조를 강조하며, 마스터 브랜치를 항상 배포 가능한 상태로 유지하는 것을 원칙으로 한다.
이 전략의 핵심은 환경 브랜치를 활용하는 것이다. 가장 일반적인 형태는 master 브랜치에서 production 브랜치를 분기시키는 방식이다. 모든 기능 개발은 master 브랜치에 대한 기능 브랜치에서 이루어지며, 완성된 기능은 머지 리퀘스트를 통해 master 브랜치로 통합된다. 이후 master 브랜치의 변경사항은 production 브랜치로 수동 또는 자동으로 병합되어 실제 서비스에 배포된다. 이 구조는 개발, 스테이징, 프로덕션과 같은 다양한 배포 환경을 명확하게 구분하고 관리하는 데 유용하다.
GitLab Flow는 이슈 추적 시스템과의 긴밀한 통합을 장려한다. 각 기능 브랜치는 특정 이슈를 해결하기 위해 생성되며, 머지 리퀘스트를 통해 코드 리뷰와 테스트 자동화를 거친 후에만 메인 브랜치에 병합된다. 이 과정은 코드 품질을 유지하고 변경 이력을 명확하게 추적하는 데 도움을 준다. 또한 보호된 브랜치 설정을 통해 메인 브랜치에 대한 직접적인 푸시를 방지함으로써 안정성을 높인다.
Git Flow에 비해 GitLab Flow는 브랜치 종류가 적고 규칙이 단순하여 학습 곡선이 낮다는 장점이 있다. 특히 DevOps 문화와 CI/CD 파이프라인을 구현하는 현대적인 소프트웨어 개발 팀에게 적합한 모델로 평가받는다. 그러나 릴리스 주기가 길거나 여러 버전을 동시에 유지관리해야 하는 복잡한 프로젝트에는 Git Flow가 더 적절할 수 있다.
5.3. Trunk-Based Development
5.3. Trunk-Based Development
트렁크 기반 개발은 Git Flow와 대비되는 단순한 브랜치 전략이다. 이 방식에서는 개발자들이 짧은 생명 주기를 가진 기능 브랜치를 만들어 작업하거나, 아예 트렁크라고 불리는 단일 메인 브랜치(예: master 또는 main)에 직접 커밋을 한다. 핵심 목표는 통합을 최대한 자주, 빠르게 수행하여 병합 충돌을 최소화하고 지속적 통합을 촉진하는 데 있다.
이 전략에서는 장기간 유지되는 기능 브랜치를 만들지 않는다. 대신, 모든 변경 사항은 가능한 한 빨리 트렁크에 통합되며, 이는 하루에 여러 번 이루어질 수 있다. 이를 위해 기능 토글이나 기능 플래그를 사용하여 아직 완성되지 않은 기능을 코드 베이스에 숨겨둔 채로 통합하기도 한다. 이 접근법은 애자일 및 데브옵스 환경에서 특히 선호된다.
트렁크 기반 개발의 주요 장점은 병합의 복잡성이 낮고, 통합 테스트가 지속적으로 이루어지며, 배포 가능한 상태의 코드 베이스를 유지하기 쉽다는 점이다. 반면, 모든 개발자가 높은 수준의 테스트 자동화와 소프트웨어 공학 실무에 익숙해야 하며, 철저한 코드 리뷰 문화가 필요하다는 점이 도전 과제로 꼽힌다. 이 모델은 지속적 배포를 목표로 하는 팀에게 적합한 전략이다.
