Git-flow 전략

김민규·2021년 9월 29일
0

서론

한이음 프로보노 공모전에 제출할 모두의 복지 어플을 개발하면서 나를 포함한 개발자 5명이 함께 협업을 진행하고 있습니다. 어플을 개발하면서 중간에 수정사항도 많고 짧지 않은 기간을 진행하는 만큼 코드와 버전관리에서 어려움을 겪고 있었습니다. 우리는 우아한형제들 기술블로그를 참고해 Git-flow 전략을 도입해 코드와 버전관리를 진행하기로 결정했습니다. 이 포스트에서 우리가 어떻게 Git-flow 전략을 사용하는지 자세히 설명하겠습니다.

Git Repository 구성 살펴보기

먼저 현재 Git Repository 구성부터 살펴보겠습니다.
Repository는 Upstream Remote Repository(이하 Upstream Repository), Origin Remote Repository(이하 Origin Repository), Local Repository 이렇게 3부분으로 구성됩니다. Upstream Repository는 개발자들이 공유하는 저장소로 최신 소스코드가 저장되어 있는 원격 저장소입니다. Origin Repository는 Upstream Repository를 Fork한 원격 개인 저장소입니다. Local Repository는 내 컴퓨터에 저장되어 있는 개인 저장소입니다.

위 그림은 Git Repository 구성과 워크플로우를 설명하고 있습니다. Local Repository에서 작업을 완료한 한 후 작업 브랜치을 Origin Repository에 push합니다. 그리고 Github에서 Origin Repository에 push한 브랜치를 Upstream Repository로 merge하는 Pull Request를 생성하고 코드리뷰를 거친 후 merge 합니다. 다시 새로운 작업을 할 때 Local Repository에서 Upstream Repository를 pull 합니다.

작업 할 때 지켜야할 서로 간의 약속

우리는 작업을 할 때 지켜야 할 약속들을 정의했습니다.
1. 작업을 시작하기 전에 JIRA 티켓을 생성합니다.
2. 하나의 티켓은 되도록 하나의 커밋으로 합니다.
3. 커밋 그래프는 최대한 단순하게 가져갑니다.
4. 서로 공유하는 브랜치의 커밋 그래프는 함부로 변경하지 않습니다.
5. feature 브랜치는 하나의 최소 기능을 개발하는 것이 좋지만 만약 feature branch에서 하위 기능을 개발할 시 feature 브랜치 밑의 하위 branch를 만듭니다.
6. Pull Request는 일반적으로 리뷰어에게 리뷰를 받아야 하지만 우리는 각자 자신의 기능을 개발하기 때문에 merge 하기전 스스로 리뷰를 합니다.
7. 자신의 Pull Request는 스스로 merge합니다.

Git-flow 전략 간단하게 살펴보기

Git-flow를 사용했을 때 작업을 어떻게 하는지 살펴보기 전에 먼저 Git-flow에 대해서 간단히 살펴보겠습니다. Git-flow에는 5가지 종류의 브랜치가 존재합니다. 항상 유지되는 메인 브랜치(main, develop)와 일정 기간 동안만 유지되는 보조 브랜치(feature, release, hotfix)가 있습니다.

  • master : 제품으로 출시될 수 있는 브랜치
  • develop : 다음 출시 버전을 개발하는 브랜치
  • feature : 기능을 개발하는 브랜치
  • release : 이번 출시 버전을 준비하는 브랜치
  • hotfix : 출시 버전에서 발생한 버그를 수정 하는 브랜치

Git-flow를 설명하는 대표 그림입니다.

위 그림을 일반적인 개발 흐름으로 살펴보겠습니다.
처음에는 master와 develop 브랜치가 존재합니다. 물론 develop 브랜치는 master에서부터 시작된 브랜치입니다. develop 브랜치에서는 상시로 버그를 수정한 커밋들이 추가됩니다. 새로운 기능 추가 작업이 있는 경우 develop 브랜치에서 feature 브랜치를 생성합니다. feature 브랜치는 언제나 develop 브랜치에서부터 시작하게 됩니다. 기능 추가 작업이 완료되었다면 feature 브랜치는 develop 브랜치로 merge 됩니다. develop에 이번 버전에 포함되는 모든 기능이 merge 되었다면 QA를 하기 위해 develop 브랜치에서부터 release 브랜치를 생성합니다. QA를 진행하면서 발생한 버그들은 release 브랜치에 수정됩니다. QA를 무사히 통과했다면 release 브랜치를 master와 develop 브랜치로 merge 합니다. 마지막으로 출시된 master 브랜치에서 버전 태그를 추가합니다.

Git-flow를 이렇게 하고 있어요

우리가 실제로 작업하는 방식을 알아보겠습니다.
먼저 사용할 Branch를 설명합니다.

  • Repositories
    • upstream (Upstream Repository)
    • origin (Origin Repository)
  • Branches
    • feature-user (사용자 관련 기능을 구현하는 feature branch)
    • TW-10_login_layout (사용자 관련 기능 중 로그인 레이아웃 작업 branch)

1. 티켓 처리하기

앞서 ‘작업을 할 때 지켜야 할 서로 간의 약속’에서 ‘하나의 티켓은 되도록 하나의 커밋으로 한다’라고 했습니다. 그래서 기능을 구현하기 전에 여러 개의 티켓으로 작업을 먼저 나누게 됩니다. 나눠진 작업 티켓 중 ‘로그인 레이아웃 생성’이라는 티켓이 있고 이 티켓을 처리한다고 가정하고 살펴보겠습니다.

  1. upstream/feature-user 브랜치에서 작업 브랜치(TW-10_login)를 생성합니다.
    (feature-user)]$ git fetch upstream
    (feature-user)]$ git checkout -b TW-10_login_layout –track upstream/feature-user

  2. 작업 브랜치에서 소스코드를 수정합니다.

  3. 작업 브랜치에서 변경사항을 커밋합니다. (커밋 메시지 규칙에 맞춰 커밋 메시지를 작성합니다.)
    (TW-10_login_layout)]$ git commit -m "Feat: #TW-10 - 로그인 레이아웃 생성"

  4. 만약 커밋이 불필요하게 어려 개로 나뉘어져 있다면 squash를 합니다. (커밋 2개를 합쳐야 한다면) (생략 가능)
    (TW-10_login_layout)]$ git rebase -i HEAD~2

  5. 커밋 그래프를 단순하게 하려면 작업 브랜치를 feature-user에 rebase합니다. (생략 가능)
    (TW-10_login_layout)]$ git pull –rebase upstream feature-user

  6. 작업 브랜치를 origin에 push합니다.
    (TW-10_login_layout)]$ git push origin TW-10_login_layout

  7. Github에서 TW-10_login_layout 브랜치를 feature-user에 merge하는 Pull Request를 생성합니다.

merge전에는 리뷰어가 따로 없기에 스스로 최종 확인을 한 후 진행합니다. 위의 절차에서 4, 5의 squash와 rebase에 대해 더 자세히 알고싶으시다면 Merge, Squash, Rebase 이해하기를 참고해주세요.

2. develop 변경사항을 feature로 가져오기(Optional)

작업을 할 때 브랜치의 수명은 되도록 짧게 가져가는 게 좋지만, feature 브랜치에서 기능을 완료하는 데 걸리는 시간이 길어지는 경우가 있습니다. 그러다 보면 develop에 추가된 기능들이 필요한 경우가 종종 생깁니다. 그럴 때는 feautre 브랜치에 develop 브랜치의 변경사항들을 가져와야합니다.
1. feature-user 브랜치에 upstream/develop 브랜치를 merge합니다.
(feature-user)]$ git merge –no-ff develop
2. upstream/develop의 변경사항이 merge된 feature-user를 upstream에 push 합니다.
(feature-user)]$ git push upstream feature-user

3. 완료된 기능을 이번 출시 버전에 포함시키기

feautre-user 브랜치에서 작업하던 기능을 완성했다면 feature 브랜치를 이번 출시 버전에 포함시키기 위해 develop에 merge해야합니다.
1. develop 브랜치에 feature-user 브랜치를 merge 합니다.
2. upstream/feature-user 기능이 merge된 develop를 upstream에 push 합니다.

4. QA 시작하기

이번 버전에 포함되어야 할 기능들이 모두 완료되었습니다. 이 후, QA를 시작하기 위해 먼저 release 브랜치를 생성하고 upstream에 push하여 release 브랜치를 공유합니다.

  1. release-1.0.0 브랜치를 생성합니다.
    (develop)]$ git fetch upstream
    (develop)]$ git checkout -b release-1.0.0 –track upstream/develop

  2. release-1.0.0 브랜치를 upstream에 push합니다.
    (release-1.0.0)]$ git push upstream release-1.0.0

5. QA 중 버그 수정하기

이번 버전에 포함되어야 할 기능들이 모두 완성되었다면 QA를 시작하기 위해 release 브랜치를 만듭니다. 그리고 QA를 진행하며 보완점을 보완하고 버그를 픽스합니다. 이 때 버그들도 티켓이기 때문에 release 브랜치에서 '1. 티켓 처리하기'와 같은 방법으로 처리합니다.

  1. release 브랜치에서 버그 티켓에 대한 브랜치를 생성합니다.
    (release-1.0.0)]$ git checkout -b TW11_bug_login_id_max_length

  2. 버그를 수정합니다.

  3. 작업 브랜치에 버그 수정 사항을 커밋합니다.
    (TW11_bug_login)]$ git commit -m "TW-11 로그인 아이디 길이 제한 버그 수정"

  4. 작업 브랜치를 origin에 push 합니다.
    (TW-11_bug_login_id_max_length)]$ git push origin TW-11_bug_login_id_max_length

  5. Github에서 TW-11_bug_login_id_max_length 브랜치를 release-1.0.0에 merge 하는 Pull Request를 생성합니다.

스스로 최종 확인을 한 후 자신의 Pull Request를 merge합니다.

6. 앱 출시

발생하는 버그들을 모두 수정했다면 이젠 출시를 준비할 때입니다. release 브랜치를 master 브랜치와 develop 브랜치에 merge하고 마지막으로 master 브랜치에서 버전 태그를 달아줍니다.
1. release 브랜치를 최신 상태로 갱신합니다.
2. release 브랜치를 develop 브랜치에 merge합니다.
3. develop 브랜치를 upstream에 push 합니다.
3. release 브랜치를 master 브랜치에 merge합니다.
4. 1.0.0 태그를 추가합니다.
마지막으로 앱을 출시합니다.

Reference

https://techblog.woowahan.com/2553/

0개의 댓글