Git(git flow)의 일반적인 작업흐름은 기능 분기를 사용하며, 여기서 새로운 기능마다 별도의 분기가 생성됩니다. 개발자는 이러한 격리된 분기에 새로운 기능을 구현한 다음 변경 사항을 main
또는 master
분기에 다시 병합합니다.
해당 워크플로우의 이점은 분명합니다. QA 환경에서 별도의 브랜치를 편리하게 배포하고 테스트할 수 있으며, 중요한 버그가 발견되면 main
브랜치에 병합되지 않습니다. 동일한 분기에서 문제를 수정하고 코드를 개선할 수 있습니다.
한편, 기본 분기는 지속적으로 배포 가능하며 해당 문제로부터 보호됩니다.
불행하게도 이 전략에는 병합 충돌이라는 심각한 단점이 있습니다. 어떤 시점에서는 피할 수 없는 오래 지속되는 분기의 경우 이러한 충돌을 해결하기가 너무 어려울 수 있으므로 분기를 완전히 제거하고 처음부터 시작하는 것이 더 쉬워집니다.
또한 충돌이 많은 경우 병합 결과를 예측할 수 없을 수도 있습니다.
그러나 이것이 가능한 유일한 전략은 아니며, 이 기사에서는 위에 나열된 단점 없이 새로운 제품 기능을 관리하는 대체 방법을 다룰 것입니다.
Git 설계에 따르면 브랜치에 동일한 파일 라인에 다른 내용이 있는 경우 병합 중에 병합 충돌이 발생합니다.
이를 설명하기 위해 두 팀이 동일한 서비스에 대한 업데이트를 구현하는 시나리오를 고려해 보겠습니다. A팀은 신용카드 지원을 통합하고, B팀은 사용자 프로필 페이지를 개편하고 있습니다. 이러한 기능은 서로 관련이 없는 것 같습니다.
그런데 기존에 결제 관련 코드가 프로필 페이지 코드와 같은 위치에 있던 것으로 밝혀졌습니다. 따라서 두 팀 모두 코드를 별도의 브랜치로 추출하고 통합을 다시 작성했습니다.
이제 문제는 변경 사항을 main
브랜치에 가장 먼저 병합하고 다른 팀이 결과적인 충돌을 해결하려고 시도하는 동안 문제가 자신의 편이 아닌 척할 것인가입니다.
전체적으로 병합 충돌을 피하는 것은 불가능하지만 다음과 같은 잘 알려진 규칙을 사용하면 충돌을 더 쉽게 해결할 수 있습니다.
어떤 행동이 어렵고 두렵다면 더 자주 하세요
Git 용어로 이는 가능한 한 자주(이상적으로는 모든 커밋에서) 병합해야 함을 의미합니다. 물론 이 경우 갈등이 더 자주 발생하지만 해결이 훨씬 쉬울 것입니다.
이를 트렁크 기반 개발이라고 하며 변경 사항을 main
분기에 직접 푸시하고 불필요한 경우 분기 사용을 피하는 것을 의미합니다.
위의 예에서 두 팀이 정기적으로 변경 사항을 main
브랜치에 푸시하면 동일한 파일을 수정하려고 한다는 것을 금방 알아차릴 수 있습니다.
더욱이 그들은 문제를 완전히 피할 수도 있었습니다. 두 번째 팀은 해당 업데이트를 고려하여 첫 번째 팀이 이미 파일을 수정한 후에 변경 작업을 시작했을 것입니다.
주의 깊은 독자라면 모든 것이 훌륭해 보이지만 테스트를 어떻게 진행해야 하는지 궁금할 것입니다. 기능별 분기를 통해 출시 전에 새로운 기능 전체를 별도로 테스트할 수 있습니다. 변경 사항을 main
브랜치에 지속적으로 통합한다면 그럴 가능성은 없을 것입니다.
기능 플래그 또는 기능 토글은 런타임에 특정 기능을 토글할 수 있는 간단한 동적 플래그입니다. 일반적으로 기능 플래그를 사용하면 QA 엔지니어, 직원, 특정 고객 등과 같은 특정 사용자 그룹에 대한 기능을 활성화하거나 비활성화할 수도 있습니다.
기능 플래그에는 다음과 같은 몇 가지 추가 이점이 있습니다.
기능 플래그를 사용하면 변경 사항을 main
분기에 더 안전하게 적용할 수 있습니다. 기능 플래그가 꺼져 있는 동안에는 변경 사항이 누구에게도 영향을 미치지 않습니다.
이 기술을 사용하면 main
분기로 직접 작업하거나 수명이 짧은 분기를 만들 수 있습니다. 따라서 병합 충돌은 매우 드물고 빠르게 해결됩니다.
요약하자면, 기능 플래그와 결합된 트렁크 기반 개발은 기능 분기의 변경 사항 충돌로 인해 발생하는 많은 문제를 피하는 데 도움이 되는 훌륭한 기술입니다.
그러나 항상 그렇듯이 모든 경우에 적합한 단일 크기는 없습니다. 이는 동일한 저장소에서 작업하는 소수의 팀에 적합합니다. 이 수를 늘리려면 일반적으로 약간의 조정이 필요합니다.
또한 특정 상황과 작업에 따라 기능 분기 또는 기능 플래그를 사용하는 두 가지 방법을 모두 사용하는 것이 항상 가능합니다.