[Git] 팀프로젝트 특성에 맞는 브랜치 전략/보호 규칙/병합(Merge) 설계하기

Quartz 쿼츠·2023년 1월 2일
5

Tools & DevOps

목록 보기
3/3
post-custom-banner

0. Introduction

처음으로 팀 프로젝트에 참여하면서 코드 공유, Pull Request를 통한 협업, 브랜치 병합 등 Git을 제대로 활용하는 경험을 할 수 있었다. 첫 주차 미션이 종료되고 아래와 같이 2 가지의 문제점을 보완해야겠다는 생각이 들었고, 이를 정리한 해결 방안을 공유해보려 한다.

첫 주차 미션에서 느낀 팀 코드 저장소의 문제점
1. 프로젝트 성향을 고려한 브랜치 전략 부재
2. main, develop 등 공유 브랜치의 보호 규칙 부재

1. Git 브랜치 전략 세우기

여러 개발자가 하나의 저장소를 사용하는 팀 프로젝트 환경에서 브랜치 관리를 효과적으로 하기 위하여 다수의 브랜치 전략들이 알려져있다. 본 글에서는 잘 알려져있는 브랜치 전략들NHN 컨퍼런스에서 소개된 깃 워크플로 사례를 참고하여 필자의 팀에 적합한 브랜치 전략을 세워나가는 과정을 이야기할 예정이다.

1.1 팀 프로젝트 특성 분석하기

  • 구성원: 프론트엔드 개발자 7 명
  • 코드 구현 기간: 미션당 4 일
  • 프로젝트 진행 과정: 개인 개발 ➡️ 토론 ➡️ 베스트 코드 찾기 ➡️ 코드 통합하기 ➡️ 배포
  • 특징: 팀원 각각 미션을 구현 후 토론을 통해 하나의 베스트 프로젝트를 만들어야 함

본 팀 프로젝트는 4 일동안 주어진 과제를 구현하고 배포까지 해야 하는 단기간 프로젝트이다. 특이 사항은 기능을 나누어 개발하는 것이 아니라, 팀원 각각 완성된 프로젝트(practice)를 개발한 후 가장 좋은 코드(best practice)만 선별하여 하나의 프로젝트로 완성시켜야 하는 것이다. 첫 주차에서 브랜치 전략 부재의 문제점을 느낀 시점은 팀원 개별의 practice 코드를 관리할 때였다. 기존에는 팀 원격 저장소를 팀원들이 fork하여 practice 코드를 develop 브랜치로 Pull Request를 통해 공유하였다. 이 경우 팀 원격 저장소에서 각 코드를 보관하지 않아 PR이 close되면 확인하기 어렵다는 단점이 있었다. 또한 practice 코드와 best practice 코드 모두 develop 브랜치에 PR되어 이를 구분하기 어려웠다.

1.2 적용하기) 설계한 브랜치 전략 소개

따라서 새로운 브랜치 전략은 아래 두 가지의 큰 기준을 바탕으로 4 개의 브랜치와 서브 브랜치들로 구성하였다.

  • 팀 원격 저장소를 clone하여 모든 코드를 팀 저장소에 공유
  • main: 배포를 담당, develop: best practice 코드 담당, practice: 팀원 개별 개발 코드 담당

프로젝트 초기 설정부터 배포까지의 과정을 본 프로젝트의 브랜치 전략을 활용하여 설명하면 다음과 같다.

  1. 프로젝트 초기 구조 & CI 설정을 main 브랜치에서 완료한다.
  2. practice 브랜치를 분기하고, 팀원들은 practice 브랜치에서 각자의 이름/깃헙 아이디로 된practice sub-branch를 분기하여 practice 코드를 작성한다.
  3. practice sub-branch에서 개발이 완료되면 practice 브랜치로 PR을 올려 토론 후 best practice를 선정한다.
  4. CD 설정을 마치고 develop 브랜치를 분기한다.
  5. develop 브랜치에서 기능/issue 별로 develop sub-branch를 분기하여 선정된 best practice를 바탕으로 코드를 작성한다.
  6. develop sub-branch에서 개발이 완료되면 PR을 통해 코드 리뷰를 받고, develop 브랜치에 코드를 merge하고 해당 브랜치를 삭제한다.
  7. 모든 best practice가 구현 완료되면 main 브랜치에서 develop 브랜치의 코드를 merge하여 자동 배포가 이루어지도록 한다.
  8. main의 배포된 코드에 문제가 생긴 경우 hotfix 브랜치를 생성하여 버그를 고친다.
  9. 버그가 고쳐지면 해당 코드를 main develop 브랜치로 merge하고 해당 브랜치를 삭제한다.

장점

  1. 팀 저장소에서 모든 코드를 확인할 수 있다.
  2. 코드의 목적에 맞게 브랜치를 나눌 수 있다.

단점

  1. 배포 후에도 여러 브랜치가 남아있어 혼란스러울 수 있다.
    • 팀원들의 개별 코드가 저장되어 있는 practice sub-branch들을 모두 살려두는 방식을 사용하여 나타난 단점이다.
    • 개인의 코드만 따로 확인할 수 있으므로 포트폴리오로 활용 시 필요할 수도 있다.
  2. 단기간 배포이므로 hotfix 브랜치 사용은 과도할 수 있다.
    • 팀원들과 상의 후에 전략을 수정해 볼 예정이다.

2. Git 브랜치 보호 규칙 세우기

2.1 브랜치 보호 규칙의 필요성

팀 저장소를 운영하다보면 브랜치가 실수로 삭제되거나 PR이 아닌 다른 방식으로 커밋이 추가되는 등 예상치 못한 문제가 발생할 수 있다. 필자의 경우 팀원들의 브랜치 생성을 가능하게 하기 위해 팀 멤버 권한을 Read(clone, pull 가능)에서 Write(clone, pull, push 가능)로 변경하였다가 PR되지 않은 코드가 머지되어 보호 규칙의 필요성을 느끼게 되었다.

Branch Protection Rule는 팀의 규칙으로 설정하거나 저장소별로 구분하여 설정할 수도 있다. 공식 문서다음 블로그 글을 참고하여 본 프로젝트에서는 3 개의 브랜치(main develop practice)에 규칙을 설정해보려 한다.

2.2 적용하기) 설정한 브랜치 보호 규칙 소개

main

  • Require a pull request before merging: PR을 통해서만 코드 병합
  • Require status checks to pass before merging: 테스트 코드를 통과한 코드만 병합

develop

  • Require a pull request before merging
    - Require approvals(2): 2 명 이상의 승인이 있어야 병합 가능
  • Require status checks to pass before merging
  • Require conversation resolution before merging: PR 코드 리뷰를 통해 생성된 conversation이 모두 solve되어야 병합 가능

practice

  • Require a pull request before merging
  • Lock branch: 코드를 push하지 못하는 read-only 브랜치

develop은 팀의 주요 개발이 이루어지는 브랜치이므로 다른 브랜치보다 더 빡빡한 규칙을 두었다. 코드 병합을 위해서는 PR을 생성하여 2 명 이상의 코드 승인이 필요하고, 테스트 코드를 모두 통과해야 하며, PR 리뷰가 모두 해결되어야 한다. 조건이 달성되지 않으면 아래와 같이 merge 버튼이 비활성화되어 있는 것을 확인할 수 있다. 참고 사항으로 테스트 코드에 대한 CI는 GitHub Actions를 사용해 다음 글에서 구현해두었다.

3. Merge option 선정

마지막으로 PR된 코드를 merge할 때 사용할 수 있는 세 가지 옵션을 알아보자. PR 페이지에서 아래와 같이 3 가지의 병합 방법을 선택할 수 있고, 자세한 개념은 공식 문서다음 블로그 글에서 잘 설명해주고 있다.

각 팀원이 개발한 best practice의 서브 브랜치로부터 develop 브랜치에 출시할 코드를 병합하는 과정을 예를 들어보자. 일반 merge 옵션을 사용할 경우 서브 브랜치의 커밋들 참조 + 머지 커밋이 추가된다. squash옵션을 사용하는 경우 스쿼시 머지 커밋만 추가되어 develop 브랜치를 깔끔하게 관리할 수 있다. rebase 옵션을 사용하는 경우 서브 브랜치 커밋들만이 추가되어 마치 하나의 브랜치에서 작업한 것과 동일한 결과물을 얻을 수 있다.

다수의 개발자가 참여하는 팀 프로젝트의 경우 squash를 사용하여 주축이 되는 브랜치를 깔끔하게 관리한다고 한다. 지난 1 주차 미션의 경우에도 main 브랜치에 무려 128 개의 커밋이 쌓여 이력 확인이 어려운 문제가 있었다. squash를 사용하면 기능에 따라 커밋 개수를 줄일 수 있는 장점이 있으나 무한 merge commit 지옥에 빠질 우려가 있다고 한다. 개인 개발단에서 rebase 등 명령어를 통해 커밋을 합치는 방법도 있다고 하니 이 옵션에 대해서는 팀프로젝트에 직접 적용해보며 결정하는 편이 낫다고 판단하였다.

참고자료

profile
Code what we love. 좋아하는 것들을 구현하고 있는 프론트엔드 개발자입니다. 사용자도 함께 만족하는 서비스를 만들고 싶습니다.
post-custom-banner

0개의 댓글