본문 바로가기

iOS

브랜칭 전략 회고(Git-flow, Github-flow, Gitlab-flow)

이전 CI/CD 회고에 대한 글 이후로, 다른 툴에 대해서도 알아보게 되었고, 그 중 GitLab에 대해 알아보다가, 우연치 않게 브랜칭 전략에 대한 글을 읽게 되었고, 필자가 제목에 있는 세 개의 브랜칭 전략에 대한 경험이 있다는 것을 새삼 깨닫게 되어 회고를 해보면 좋을 것 같아 이렇게 글을 작성하게 되었다.

우선 짧은 회고를 먼저 진행해보자면, 올해 3월에 출시한 해핏이라는 앱에서는 Git-flow를 채택하여 개발을 진행했고, 지금 다시 돌이켜 보았을때 적합한 부분도 있고 어떤 부분은 부적합하지 않았나 싶은 부분도 있다. 이에 대해서는 마지막에 정리해서 작성해보도록 하겠다.

 

당시 해핏에 적용된 룰을 기반으로 설명을 하자면, Git-flow는 메인 브랜치인 masterdevelop, 그리고 release(초기 master에서 파생되는 브랜치이다)를 중심으로 하며, 보조적인 역할을 가진 브랜치들, 예를 들어 기능추가(당시 Feat으로 브랜칭하였다), 버그대응(당시 Bug로 브랜칭하였다) 등 브랜치에 명확한 롤(role)을 부여한 브랜치들이 있다.

 

전략에 대해서 조금 더 자세히 알아보기 전에 먼저 여담을 말해보자면, 보조강사로서 일할 때에도 훈련생분들께서 가장 많이 도움을 요청한 부분이 바로 이 브랜칭 전략이었는데, 대부분의 경우 하나를 채택해서 엄격하게 지키는 것에만 초점을 맞추게 되는 경우가 많아서 조금 아쉬웠다.

개인적으로는 알려진 브랜치 전략들의 규칙을 중심으로 하되, 상황에 맞게 팀원들끼리 룰을 정하는 것이 제일 중요하다고 생각한다. 마찬가지로 본글에서, 해핏에서 적용한 Git-flow가 수 많은 개발 블로그에 작성된 그것과 완벽하게 일치하지 않을 수도 있다. 대표적인 예로,  Git-flow에는 현재 버전 개발에 해당하는 기능들을 반영하는 develop 브랜치가 있고, 다음 버전을 개발하는 release 브랜치가 나뉘어있는데(이 또한 여러 글을 참고해본 결과 두 이름과 역할이 반대로 매치되어있는 경우도 많았다),  해핏은 앱 심사를 받고 다음 기획으로 넘어가는 식으로 프로젝트가 진행이 되었기 때문에 release브랜치를 운용을 하지 않았고, 현재 버전에 해당하는 기능들을 반영하는 develop 브랜치 하나만 운용하였다.

 

다시 본론으로 돌아와, 해핏에 적용되었던 Git-flow에 대해서 이야기 하자면, 결국 이 브랜칭 전략의 중심점은 master에서 파생되는 Develop 브랜치이다. master 브랜치와 develop 브랜치는 항상 안정적인 코드가 있어야 하며, master 브랜치는 출시의 관점에서 봤을 땐 이 것이 곧 deployment의 대상인 product이고, develop 브랜치는 새로운 기능(feature)들이 merge되는 브랜치이다.

 

이를 도식화해서 나타내면 다음과 같다.

그림과 함께 이해하기 쉽게 간단히 설명하자면, 먼저 master에서 위에서 이야기한 롤에 의거하여 생성된 브랜치로 각각 뿌려준다. 이후에, feature의 하위 브랜치 f1, f2는 각각의 가상의 기능을 의미하는데, 각 기능에 해당하는 개발을 진행하는 브랜치이다. 여기서 알아두어야 하는 것은, 해핏의 경우 각 기능들에 대해서 개발자에 따른 원격 저장소를 하위에 가지고 있고, 따라서 이에 해당하는 로컬 저장소에서 개발을 하여 원격에 push를 하는 룰을 만들어 따랐다. 또 feature 브랜치는 무조건 develop에서 따오는 것이 룰이다.

다음으로 볼 부분은 bug 부분인데, 해핏의 경우 출시 후에 습관 달성 연속날짜가 변경이 안되는 버그가 있었고, 이를 핫픽스하여 이와 같은 경우엔 develop과 master에 각각 merge를 해주었다.

마지막으로, develop 브랜치의 마지막부분에서 출시될 버전에 대해 확인을 하고 master에 merge 해준다.

 

이를 JIRA와 함께 관리를 했는데, 각 이슈들을 티켓팅하여, 1 ticket 1 commit을 원칙으로 하여 처리하도록 했다

 

위와같이 bug에 해당하는 티켓이 있으면, 그 위의 도식에서 Bug 브랜치에서 이 티켓에 해당하는 커밋을 진행하고 develop과 master에 merge되는 방식이다.

 

다음으로 Github-flow는 위의 Git-flow의 복잡성을 단순화하기 위해 나온 전략이라고 한다. 이 전략에서는 Master 브랜치는 동일한 롤을 수행하지만, 따로 feature나 develop 브랜치가 존재하지 않는다. 즉, 기능추가 및 버그수정 작업을 위한 브랜치들을 master 브랜치에서 바로 따오는 방식이라고 한다. CI 자동화와 연관 지어서 이 전략을 promoting하는 글들이 많았는데, 즉, Local - Remote로 push 후에 PR 리뷰를 통해 master에 merge가 되면 바로 CI를 통과시키고 deploy하는 방식인 것이다.
마지막 부분에 추가적으로 설명하겠지만 Git-flow에서는 rebase-merge가 주로 사용된다고 하면, 이 전략에서는 Github의 Pull request를 그대로 이용하는 식인 것 같다. 그리고 이 PR의 리뷰과정에서 master 브랜치, 즉 프로덕트 레벨로 바로 올라갈 코드이기 때문에 상당히 조심해야할 것이다. 이러한 PR과 코드리뷰 기능에 집중하여 github-flow라는 이름이 붙여진 것이라고 한다. 사실 개발을 처음 배우면서 버전관리를 처음으로 적용할 때 이 방식으로 하게 될 것이다.(물론 배포는 안하겠지만)

이러한 이유에서 보조강사로서 활동할 때, 훈련생들에게 먼저 추천한 방식이다.

 

다음으로, 외주를 하며 경험한 GItlab-flow는 마찬가지로 Git-flow의 복잡성을 단순화하기 위해 나온 전략이며, CI / CD tool 인 GitLab에서 만들었다고 한다. 설명의 양만 보아도 알겠지만 Github-flow는 master브랜치로 가기까지의 과정이 너무나도 간단하기 때문에 매우 불안정하며 배포, 릴리즈 등의 복잡한 이슈들에 대응이 불가능하다. GitLab-flow에서는 그 이름에 걸맞게 CI/CD 파이프라인에 초점을 맞추고 있다.

우선 master에서 각각 feature, production, pre-production(스테이징 서버를 의미하고 선택사항이다)으로 뿌려진다.

이 전략에서는 이전과는 달리 master은 git-flow의 develop 브랜치의 역할을 하고, master 브랜치에서 테스트가 진행되고 deploy가 진행되는 브랜치는 따로 production 브랜치이다. 따라서 production 브랜치는 이전 전략들의 master 브랜치와 같은 역할을 한다. 따라서 이 전략에서는, feature 브랜치들은 master 브랜치에서 브랜칭이 되고 머지가 된다.

여기서, master 브랜치와 production 브랜치 사이에 pre-production 브랜치를 거치는데, 여기서는 stage server 레벨에서 통합테스트를 진행하게 된다. 이 글을 쓰기 위해 조사하면서, 몇몇 분들은 운영서버를 그대로 stage에서 이용한다고 하는 분들도 계셨는데, 일반적인지는 모르겠으나 필자는 stage 서버라는 클론 서버가 존재하여 deploy 전 최종 검수를 하는 레벨이었다.

경험담에 대한 이야기는 자세히는 못하지만, git-flow를 적용할 만큼 큰 규모가 아니지만, github-flow에서 커버를 하지 못하는 deploy와 release 등의 CI 과정을 커버해야하는 경우에 사용된다고 생각하고 있다.

 

마지막으로 그 당시의 회고를 하며 정리해보도록 하겠다.

사실 처음 hapit의 레포지토리에 들어가 브랜치를 확인하면 굉장히 지저분한 걸 볼 수 있는데, 실제로 Git-flow 전략 자체가 브랜치가 굉장히 많이 생긴다는 점이 단점으로 꼽히곤 한다지만, 사실 저렇게 된 이유는 rebase를 하지 않아서 그렇다. 사실 당시에 rebase를 하면서 한번 꼬인적이 있어서, 얼마 남지 않은 프로젝트 기간에 rebase를 계속하며 문제상황에 직면을 하고 싶지 않아서 merge만 진행했기에 저렇게 된 것이다.

이 것이 내가 처음에 말했던 적합하지 않은 전략이었던 이유이다. 짧은 기간 안에 광범위한 기획을 감당하기엔 Git-flow는 꽤 복잡한 전략이었던 것 같다. 또한 프로덕트가 존재하는 상황에서 계속 버전 업그레이드를 했던 기간보다, 첫 출시를 위해 개발한 기간이 길기 때문에 적합하지 않다고 판단한 것이다.

하지만 반대로 굉장히 적합했다고 생각한 부분도 있다. 말했다시피 개발기간이 빡빡했던 탓에 우리는 후반에 갈수록 JIRA를 위주로 소통을 했다. 이 때, 세세하게 나뉘어있는 브랜치 덕분에 각자 담당한 파트들이 명확해졌고, JIRA업데이트와 PR 리뷰만 계속 진행하면서 차질없이 신속하게 개발이 이루어지는 것을 보며 쾌감을 느꼈던 경험이 있다. 이러한 부분이 프로젝트에 굉장히 적합했다고 느낀 부분이다. (사실 해핏 이전의 프로젝트들에는 따로 전략을 두지 않거나 Github-flow와 비슷하게 했지만, 해핏의 경우엔 내가 공들여 학습한 JIRA의 활용을 극대화하기 위해 Git-flow를 채택한 것도 있다ㅎㅎ)