Skip to content

GitFlow

Nathan edited this page Dec 20, 2020 · 2 revisions

Git


  • Git은 버전 관리 시스템 (혹은 형상 관리 도구)로 소프트웨어 개발의 코드를 효과적으로 관리하게 해준다.
  • 주로 Git은 mater brach을 기준으로 각 프로젝트에 대한 형상 관리를 진행을 하게 된다.
    • 여기서 브랜치란 해당 레파지토리에 추가적인 독립 공간을 만들어 작업을 진행할 수 있도록 해준다.
    • 그래서 mater 브랜치를 기준으로 다양한 branch를 생성해 개발을 진행하는 경우가 대부분이다.

Decentralized but centralized


image

  • git repository를 구성을 하게 되면, 많은 사람들이 해당 repository를 받아 각 로컬에서 작업을 진행할 수 있다고, 각자 작업을 진행을 하면, origin repo에 push 혹은 pull을 진행하게 된다.
  • 결국, 각자 remote을 통해 작업 repository를 받아 로컬에서 작업을 해 Decentralized 같은 방식처럼 보이지만, 결국에는 origin에 모두 적용한다는 점에서 centralized하다고 볼 수 있다.
  • 그래서 Git을 효율적으로 사용하기 위해서는 Decentralized but centralized 특징을 잘 이용해야 하기 때문에 다양한 Git 브랜치 전략을 활용하게 되는 것이다.

Git flow


image

  • 위 그림은 Git flow을 설명하는 대표적인 그림이고, Git flow 전략에 브랜치 종류는 총 5가지가 존재한다.
    • master : 제품으로 출시될 수 있는 브랜치
    • develop : 다음 출시 버전을 개발하는 브랜치
    • feature : 기능을 개발하는 브랜치
    • release : 이번 출시 버전을 준비하는 브랜치
    • hotfix : 출시 버전에서 발생한 버그를 수정 하는 브랜치
  • 이제 위 5가지 브랜치에 대한 역할을 파악하면서, Git-flow 전략에 대해 알아보자.

Main Branches


image

  • Git flow에서 가장 중요한 Main Branch는 matster, develop이다.
  • master 브랜치는 현재 product가 배포 및 운영이 되는 코드라고 보면된다.
  • 반면, develop 브랜치는 현재 배포 중인 product의 새롭게 배포할 버전에 대한 코드라고 보면 된다.
  • 즉, Git flow는 master, develop 브랜치를 기준으로 운영중인 혹은 준비중인 product에 대한 실제 배포 버전을 관리한다고 보면 된다.

Supporting Branch


image

  • Git flow는 main branch 이외에도, main branch를 보조하는 Supporting Branch가 존재한다.
    • Feature branches
    • Release branches
    • Hotfix branches
  • 개발중인 product는 언제든지 새로운 기능이 추가될 수 있고, truble이 발생 수정이 필요한 경우가 무조건 존재한다.
  • 그래서 Git flow는 Supporting Branch들을 통해 운영중인 product를 유지 보수하게 된다.
  • Supporting Branch들은 main branch와 달리 수명이 존재하고, 수명이 다한 브랜치는 삭제가 된다.
  • Supporting Branch 수명 혹은 생명 주기는 명확히 정해진 것이 아니라 아마 Git flow을 사용하는 팀마다 유동적으로 가져가는 거 같다.

Feature branches

  • Feature branches들은 대게 다음 릴리즈될 product에 대한 새로운 기능을 추가하는 브랜치들이다.
  • 위 그림 같이 develop 브랜치로부터 파생되어, 추가될 기능이 모두 구현하게 되고, 다시 develop브랜치에 Merge 되거나 해당 기능이 다음 릴리즈에 필요없게 된다면 삭제한다.

작업 흐름

  1. feature 브랜치 생성

    $ git checkout -b myfeature develop
  2. feature 브랜치에서 새로운 기능 추가 작업이 끝난 후 다시 develop 브랜치로 Merge

    $ git checkout develop 
    develop 브랜치로 이동 'develop'
    
    $ git merge --no-ff myfeature
    개발이 완료된 feature 브랜치 merge
    
    $ git branch -d myfeature
    merge된 feature 브랜치 삭제
    
    $ git push origin develop

참고 - git merge 에서 —ff & —no —ff 차이

image

  • git merge는 기본 옵션으로 —ff가 붙는데, 여기서 ff는 fast-forward의 약자로 merge를 시도할 때 두 브랜치의 마지막 commit간의 관계를 비교해서, 한 commit의 이력이 다른 커밋에 이력에 포함될 경우 새로운 merge commit을 생성하지 않고 해당 commit을 그대로 가져가게 된다.
  • 위 그림을 예로, develop 브랜치의 두 번째 commit에서 feature 브랜치로 분기한 다음,3개의 커밋을 작성한 뒤 이를 merge하고자하는 상황이다.
  • 이 때, fast-foward 옵션이 적용된 상황이라면 (merge의 default 설정)develop 브랜치에서 분기해나간 feature의 commit을 가져올 때,develop 입장에서는 feature의 commit history를 동일하게 가져도 문제가 없다고 판단되어 feature 를 rebase를 한 것처럼 커밋 이력을 그대로 가져온다.
  • 하지만, --no-ff 옵션이 적용된다면 develop의 마지막 commit 이력이 feature commit의 이력에 그대로 포함되더라도 새로운 merge commit을 생성하게 된다.
  • 사용 시점은 목적에 따라 다르긴 할텐데, 가령 git flow를 관리할 때 master나 release 같이 다른 브랜치의 커밋을 단위로 묶어 관리할 때 유용한 기능인 것 같다.

Release Braches

  • Release Braches는 말 그대로 다음 버전을 출시할 브랜치를 의미하게 된다.
  • develop에서 다음 릴리즈할 개발이 끝나고 릴리즈릴 하기 위해 해당 코드를 테스트 및 버그를 잡아내는 브랜치이다.

흐름

$ git checkout -b release-1.2 develop
릴리즈할 버전을 의미하는 브랜치를 develop 브랜치로부터 생성.

$ ./bump-version.sh 1.2
쉘 스크립트 파일에 항상 새롭게 릴리즈할 버전에 대해 반영을 함.

$ git commit -a -m "Bumped version number to 1.2"
  • 릴리즈할 버전에 대한 테스트 혹은 버그를 잡아내는 작업이 완료가 되면, master 브랜치에 Merge를 진행하게 된다.
$ git checkout master

$ git merge --no-ff release-1.2
master 브랜치로 merge

$ git tag -a 1.2
tagging
  • 여기서 다른 브랜치 작업과 달리 tagging 작업을 진행하는데, tagging은 나중에 이전 릴리즈에 대한 참조를 위해 tagging을 진행한다.
  • 그리고 다시 develop 브랜치로 돌아가 develop 브랜치에 현재 릴리즈된 버전을 merge 하고, develop 브랜치까지 merge가 완료되면 release 브랜치는 더이상 필요가 없기 때문에 삭제한다.
$ git checkout develop

$ git merge --no-ff release-1.2

$ git branch -d release-1.2

Hotfix branches

image

  • 현재 운영 master 브랜치에서 버그 발생 했을때, hoxfixes 브랜치를 만들어 해당 버그를 잡고, 버그를 잡은 버전을 다시 배포하게 된다.
  • 위 과정은 Release 브랜치 작업 과정과 유사하나, 버전이 1.2.1 같이 새로운 기능이 추가된 Release와 구분을 해야한다.

흐름

// hotfix branch
$ git checkout -b hotfix-1.2.1 master
버그 발생 버그를 해결하기 위한 작업 브랜치 생성.

$ ./bump-version.sh 1.2.1
버그 수정에 대한 버전 저장

$ git commit -a -m "Bumped version number to 1.2.1"
버그 수정 작업 시작을 알리는 커밋

$ git commit -m "Fixed severe production problem"
작업 완료 

// master branch
$ git checkout master

$ git merge --no-ff hotfix-1.2.1
master 브랜치로 merge

$ git tag -a 1.2.1
tagging

// develop branch
$ git checkout develop

$ git merge --no-ff hotfix-1.2.1
master에 merge가 완료 된 후 develop 브랜치에도 merge 진행.

$ git branch -d hotfix-1.2.1

마무리


  • git flow 이외에도 github flow, gitlab flow 등과 같이 다양한 전략이 존재한다.
  • 근데, 여기서 중요한 점은 어떤 전략이 무조건적으로 좋다는 것보단 현재 내가 운영중인 서비스 혹은 운영할 서비스의 목적 그리고 팀 협업 관점에서 효율적이고 적합한 전략을 선택하는 것이 중요한 거 같다.
  • 그래서, 많은 사람들이 한 가지 전략에 맹신하지 말고 적절하게 팀 혹은 서비스에 맞게 변형해서 사용하라고 강조한다.

참고


A successful Git branching model

우린 Git-flow를 사용하고 있어요 - 우아한형제들 기술 블로그

Clone this wiki locally