Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

Gitflow

Git은 버전 관리 시스템이고 GitFlow는 Git의 분기 모델이다. 프로젝트는 기능개발, 핫픽스, 스테이징, 릴리즈 등의 다양한 분기를 가진다. Gitflow는 제품 개발에 사용 할 수 있는 워크플로우를 Git으로 체계화했다.

gitflow 설치

gitflow는 git을 이용한 워크플로우 모델일 뿐이다. 따라서 git이 가지고 있는 기능만으로 gitflow를 그대로 따라 갈 수 있다. 하지만 git flow 툴을 이용하면 좀 더 쉽게 워크플로우를 구성 할 수 있다. gitflow를 설치해 보자.

# apt-get install -f git-flow

제품 개발 워크플로우 관점에서 Gitflow

기본 브랜치

제품 개발의 기본 자산이 되는 코드의 분기는 브랜치로 관리한다. Gitflow의 기본 브랜치들을 확인해보자.

  • Develop 브랜치 : 개발자들이 개발을 시작하는 브랜치다. Develop 브랜치는 Feature 개발과 Release 브랜치의 기반이 된다.
  • Master 브랜치 : develop 브랜치는 Stable한 브랜치가 아니다. Master 브랜치가 Stable한 브랜치가 된다. 즉 기본 자산이 되는 코드가 여기에 위치한다. 여기에서 배포를 한다는 것은 Stable한 코드가 배포된다는 것을 의미한다. Master 브랜치에 프러덕트의 현재 상태가 태깅(Tagging) 된다.
  • Feature : 개발은 "버그수정"과 "기능개발"두개로 나뉜다. Feature는 기능개발을 위한 브랜치다. 새로운 개발이 필요할 경우 개발자는 Develop 브랜치로 부터 Feature 브랜치를 분기한다.
  • Release : 여기에서 배포가 이루어진다. Develop 브랜치에서 만들어진다. 여기에서 통합테스트, 모니터링, 버그 수정 등이 끝난 후에 develop 브랜치와 master 브랜치로 merge 한다.
  • hotfix : Release 브랜치에서 테스트, 버그 수정이 끝나면 Master 브랜치로 merge 되어서 실제 배포되어서 운영단계로 넘어간다. 운영 단계에서 버그가 발생 할 수 있는데, 이 경우 hotfix

git flow를 이용해서 브랜치 생성

# git flow init       
/home/yundream/workspace/gitflow/.git/ 안의 빈 깃 저장소를 다시 초기화했습니다
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master] 
Branch name for "next release" development: [develop] 

How to name your supporting branch prefixes?
Feature branches? [feature/] 
Bugfix branches? [bugfix/] 
Release branches? [release/] 
Hotfix branches? [hotfix/] 
Support branches? [support/] 
Version tag prefix? [] 
Hooks and filters directory? [/home/yundream/workspace/gitflow/.git/hooks] 

Master와 Develop 브랜치

기본 브랜치인 develop와 master가 만들어진 걸 확인 할 수 있다.
# git branch
* develop
  master

 Git develop, master

Master는 공식으로 릴리즈될 코드 자산이다. Develop의 내용은 최종적으로 Master 브랜치에 통합될 것이다. Master 브랜치는 릴리즈 버전이 태깅이 될 것이다. 버전 태깅은 보통 feature 단위로 수행한다. 대략 아래와 같은 워크플로우를 예상 할 수 있을 것이다.
  1. 현재 릴리즈 버전은 v0.5 다. 우리는 v1.0을 기획 하고 있다.
  2. v1.0에 추가할 feature를 식별한다.
  3. 해당 feature에 v1.0을 태깅한다.
  4. 관리자와 개발자는 v1.0 태깅된 feature 들을 개발하게 된다. 결과적으로 릴리즈할 기능을 추적할 수 있게 된다.
Master 브랜치와 Develop 브랜치가 분리되기 때문에 릴리즈된 코드를 안전하게 유지 할 수 있다.

Feature 개발

이제 Master는 안정적으로 돌아가고 있다. 기획자는 다음 기능을 기획하게 될 것이고, 이건 개발 feature로 만들어진다. 이 feature는 user story로 만들어지고 Jira Task로 정리된다. 개발자들은 Develop 브랜치에서 Feature 브랜치를 만들어서 개발을 한다.

 Feature 개발

feature_001 을 개발해보자.
# git flow feature start feature_001
새로 만든 'feature/feature_001' 브랜치로 전환합니다

Summary of actions:
- A new branch 'feature/feature_001' was created, based on 'develop'
- You are now on branch 'feature/feature_001'

Now, start committing on your feature. When done, use:

     git flow feature finish feature_001

# git branch
  develop
* feature/feature_001
  master

개발이 끝나면 아래 명령으로 merge 한다.
# git flow feature finish feature_001
브랜치가 'origin/master'보다 1개 커밋만큼 앞에 있습니다.
  (로컬에 있는 커밋을 제출하려면 "git push"를 사용하십시오)
업데이트 중 8fbeac3..1f7e161
Fast-forward
 Feature_001.md | 1 +

Release 브랜치

기능(Feature) 개발이 완료되면, develop 브랜치로 부터 release 브랜치를 만든다. 여기에서는 만들어진 기능에 대한 QA를 한다. 이번 Release에 배포할 모든 기능에 대한 QA가 끝나면 release 브랜치를 master와 develop 브랜치로 merge 하고, master 브랜치에 버전을 태깅한다.

 Release

Release를 위한 전용의 브랜치를 운영하기 때문에, 이번 release를 준비하면서 동시에 다음 번 release를 준비 할 수 있다. 이번 release에 배포하기로 했던 기능이 여러 이유로 배포할 수 없게 된 경우에도 유연하게 대응 할 수 있다.

# git flow release start 0.1.0

QA가 완료됐다면 release 한다.
# git flow release finish '0.1.0'
Branches 'develop' and 'origin/develop' have diverged.
And local branch 'develop' is ahead of 'origin/develop'.
'master' 브랜치로 전환합니다
브랜치가 'origin/master'에 맞게 업데이트된 상태입니다.
Merge made by the 'recursive' strategy.
 Feature_001.md | 1 +
 Feature_01.md  | 1 +
 2 files changed, 2 insertions(+)
 create mode 100644 Feature_001.md
 create mode 100644 Feature_01.md
master 브랜치로 전환하면서 merge 되는 걸 확인 할 수 있다.

hotfix 브랜치

이렇게 해서 제품 개발과 릴리즈가 분리가 됐다. 릴리즈 브랜치에서 QA를 마치고 배포된 코드라고 하더라도 운영 중에 버그를 발견 할 수 있다. 이 경우 master 브랜치를 기반으로 hotfix 브랜치를 만들어서 문제를 해결한다.

 hotfix gitflow

문제가 해결되면 현재 master 분기에 병합되어야 하며 업데이트 된 버전 번호로 태그릴 지정해야 한다.

버그수정을 위한 별도의 개발라인을 운영함으로써 다른 개발 워크플로우를 중단하거나 릴리즈를 중단시킬 필요가 없다. 새로운 hotfix를 시작한다.
# git flow hotfix start hotfix_001 

버그를 수정하고 hotfix를 merge 한다.
# git flow hotfix finish hotfix_001
Branches 'master' and 'origin/master' have diverged.
And local branch 'master' is ahead of 'origin/master'.
Branches 'develop' and 'origin/develop' have diverged.
And local branch 'develop' is ahead of 'origin/develop'.

hotfix가 master 브랜치와 develop 브랜치에 merge 된 것을 확인 할 수 있다.

프로젝트 진행 연습

실제 프로젝트를 진행하면서 지금 과정을 숙지하려 한다. 프로젝트 환경은 아래와 같다.
  • git 저장소 : github
  • 운영체제 : 우분투 리눅스
  • git version 2.27.0
  • git flow

프로젝트 테스트 시나리오

  1. tech_book 이라는 이름으로 github 레포지토리를 만든다. 이 프로젝트는 기술 문서를 관리한다.
  2. 프로젝트 오너(owner)가 프로젝트를 초기화 한다. 초기 프로젝트는 README.md 파일하나만 가진다.
  3. 새로운 문서 "golang_tutorial.md"를 만든다. feature 로 분기해서 개발한다.
  4. feature가 완성되면 release를 만들고 내용을 검토하고 오타를 수정한다.
  5. golang_tutorial.md release가 끝나지 않은 상태에서 새로운 문서 "golang_channel.md"를 만든다. 역시 feature로 분기된다.
  6. "golang_tutorial.md"가 완성되고 master 브랜치에 merge 된다.
  7. "golang_tutorial.md"문서에 오타가 발견된다. hotfix 브랜치를 만들어서 오타를 수정하고 mater 와 develop 브랜치에 merge 한다.
  8. golang_channel.md 문서의 release 브랜치를 만든다.

github repository

github에서 tech_book.git을 만들었다. 이 저장소를 원격 저장소로 할 것이다.
git remote add origin https://github.com/yundream/tech_book.git
git branch -M main
git push -u origin main

프로젝트 초기화

gitflow 프로젝트 초기화를 한다.
# mkdir tech_book
# cd tech_book
# git flow init
/home/yundream/workspace/tech_book/.git/ 안의 빈 깃 저장소를 다시 초기화했습니다
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master] 
Branch name for "next release" development: [develop] 

How to name your supporting branch prefixes?
Feature branches? [feature/] 
Bugfix branches? [bugfix/] 
Release branches? [release/] 
Hotfix branches? [hotfix/] 
Support branches? [support/] 
Version tag prefix? [] 
Hooks and filters directory? [/home/yundream/workspace/tech_book/.git/hooks] 

프로젝트 초기 Feature 개발

프로젝트 안내 문서인 README.md 파일도 feature 로 개발할 계획이다.
# git flow feature start tech_book_intro 
새로 만든 'feature/tech_book_intro' 브랜치로 전환합니다

Summary of actions:
- A new branch 'feature/tech_book_intro' was created, based on 'develop'
- You are now on branch 'feature/tech_book_intro'

Now, start committing on your feature. When done, use:

     git flow feature finish tech_book_intro

아래와 같이 README.md 파일을 만들었다.
## 프로젝트에 대해서
  * 기술 문서들을 관리한다. 
  * 문서 형식은 마크다운으로 통일하다.
  * 릴리즈된 문서는 github.io로 서비스 한다. 

README.md 파일을 커밋하고 feature 개발을 마무리 한다.
# git add README.md
# git commit -a
# git flow feature finish tech_book_intro
'develop' 브랜치로 전환합니다
업데이트 중 570bfb8..be4718b
Fast-forward
 README.md | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 README.md
feature/tech_book_intro 브랜치 삭제 (과거 be4718b).

Summary of actions:
- The feature branch 'feature/tech_book_intro' was merged into 'develop'
- Feature branch 'feature/tech_book_intro' has been locally deleted
- You are now on branch 'develop'
  • feature 브랜치를 develop 브랜치에 merge 한다.
  • feature 브랜치를 로컬에서 삭제한다.
  • develop 브랜치로 checkout 한다.

릴리즈 하기

develop 브랜치에 README.md 파일이 보일 것이다. release 브랜치에서 문서를 교정하고 배포 할 것이다.
# git flow release start '0.0.1'         
새로 만든 'release/0.0.1' 브랜치로 전환합니다

Summary of actions:
- A new branch 'release/0.0.1' was created, based on 'develop'
- You are now on branch 'release/0.0.1'

Follow-up actions:
- Bump the version number now!
- Start committing last-minute fixes in preparing your release
- When done, run:

     git flow release finish '0.0.1'

release/0.0.1 브랜치가 만들어졌다. README.md 파일에 오타가 보여서 수정했다.
  * 문서 형식은 마크다운으로 통일하다. 

통일하다를 "통일한다"로 수정하고 commit 한다.
# git commmit README.md -m "오타 수정"

QA가 끝났다. release 한다.
# git flow release finish '0.0.1'
'master' 브랜치로 전환합니다
Merge made by the 'recursive' strategy.
 README.md | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 README.md
이미 'master'에 있습니다
'develop' 브랜치로 전환합니다
Merge made by the 'recursive' strategy.
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
release/0.0.1 브랜치 삭제 (과거 dbc526a).

Summary of actions:
- Release branch 'release/0.0.1' has been merged into 'master'
- The release was tagged '0.0.1'
- Release tag '0.0.1' has been back-merged into 'develop'
- Release branch 'release/0.0.1' has been locally deleted
- You are now on branch 'develop'
  • release/0.0.1 브랜치가 master 브랜치에 merge 된다.
  • relaese에 0.0.1이 태깅된다.
  • develop에서 back-merge 되며 0.0.1이 태깅된다.
  • release/0.0.1 브랜치가 삭제된다.

원격 저장소 push

이제 master 브랜치와 develop 브랜치를 원격 저장소에 push 한다.
# git checkout master
# git remote add origin https://github.com/yundream/tech_book.git
# git push -u origin master
# git checkout develop
# git push -u origin develop 

hotfix 적용

README.md 문서에 일정이 빠져있어서 다음 release 전에 hotfix를 적용하기로 했다.
# git flow hotfix start hotfix_001 
새로 만든 'hotfix/hotfix_001' 브랜치로 전환합니다

Summary of actions:
- A new branch 'hotfix/hotfix_001' was created, based on 'master'
- You are now on branch 'hotfix/hotfix_001'

Follow-up actions:
- Start committing your hot fixes
- Bump the version number now!
- When done, run:

     git flow hotfix finish 'hotfix_001'

README.md 문서를 수정하고 commit 후 hotfix 브랜치를 merge 한다.
# git flow hotfix finish hotfix_001 '0.0.2'
Branches 'master' and 'origin/master' have diverged.
And local branch 'master' is ahead of 'origin/master'.
'develop' 브랜치로 전환합니다
브랜치가 'origin/develop'에 맞게 업데이트된 상태입니다.
Merge made by the 'recursive' strategy.
 README.md | 2 ++
 1 file changed, 2 insertions(+)
hotfix/hotfix_001 브랜치 삭제 (과거 f4ace63).

Summary of actions:
- Hotfix branch 'hotfix/hotfix_001' has been merged into 'master'
- The hotfix was tagged 'hotfix_001'
- Hotfix tag 'hotfix_001' has been back-merged into 'develop'
- Hotfix branch 'hotfix/hotfix_001' has been locally deleted
- You are now on branch 'develop'
master와 develop 브랜치에 merge 됐다. 각 브랜치를 원격 저장소에 push 하는 것으로 작업이 마무리 됐다.

정리

  • gitlab으로 gitflow를 적용하는 것을 정리한다.
  • gitlab CICD를 이용해서 워크플로우를 자동으로 통합/배포 하도록 한다.

참고