[Git] Git Flow
📌 목차
- Git flow란?
- Git flows 사용 이유?
- Git flow 컨셉
- Git flow 설치
- Git flow 시작
⚡️ Git Flow란
Git Flow란 실무에서 깃을 어떻게 사용 해야하는지에 대한 전반적이고 표준화된 방식입니다. 즉, Git으로 형상관리를 할때 브랜치를 효율적으로 관리하기 위해 사용하는 브랜치 관리전략입니다.
⚡️ 1. Git Flow 사용 이유
브랜치들을 굳이 전략까지 세워서 관리를 해야할까?
1-1. 브랜치 전략이 필요없는 경우
- 프로젝트의 규모가 작거나 혼자 개발을 진행하는 경우
- 버전 관리의 필요성이 없는 프로젝트를 진행하는 경우
1-2. 브랜치 전략이 필요한 경우
- 프로젝트의 규모가 이전보다 커지고 팀원이 늘어났을 경우
- 버전 관리의 중요성이 높고 히스토리 관리가 필수인 프로젝트인 경우
브랜치전략이 존재하지 않는 경우 이슈가 발생하게 되면 개발한 코드를 다시 되돌리고
이러한 과정에서 개발을 멈춰야 하는 불편함이 발생 할 수 있습니다.
📊 2. Git Flow 컨셉
- master : 기준이 되는 브랜치로 제품을 배포하는 브랜치.
- develop : 개발자들이 해당 브랜치를 기준으로 각자 작업한 기능을 merge.
- feature : 단위 기능을 개발하는 브랜치, 개발 완료 시 develop 브랜치에 merge.
- release : master 브랜치로 보내기 전에 먼저 QA(품질검사)를 하기는 브랜치.
- hotfix : master 브랜치로 배포를 했는데 버그가 생기는 경우 긴급 수정하는 브랜치.
master와 develop 브랜치가 중요한 메인 브랜치이고 나머지는 필요에 의해 운영하는 브랜치로 보시면 됩니다.
2-1. Git Flow 작업 흐름
- master branche에서 시작, 동일 branch를 develop에도 생성.
- 개발자들은 develop 브랜치에서 개발 시작.
- 추가 기능 개발을 위해 feature 브랜치 생성.
- 기능 개발 완료시 코드 리뷰를 거쳐 develop branche에 병합.
- release 브랜치를 따서 QA 진행.
- release 브랜치를 master, develop 브랜치로 보낸다.
- master 브랜치에서는 태그를 생성, 배포 진행.
- 버그 발생 시 hotfix 브랜치 생성 후 수정 배포.
2-2. 깃 플로우 메인 원격 저장소 Fork
Fork는 프로젝트를 통째로 외부로 복제해서 개발 하는 방식입니다. 여기서 핵심은 Fork한 프로젝트는 A 개발자의 원격 저장소에 위치하게 되고, A 개발자는 로컬에서 기능을 개발하여 자신의 원격 저장소에 push를 하게 되고 메인 원격 저장소에 Pull Request(PR)을 날려 머지(Merge)요청을 합니다.
⚡ 3. Git Flow 설치
3-1. Vscode 설치 방법
- VS Code의 gitflow plugin를 설치합니다.
3-2. Window 설치 방법
Extension을 사용하지 않으실 분은 아래 Window 설치 방법을 참고해주세요.
3-3. Mac 설치 방법
$ brew install git-flow
3-4. Linux 설치 방법
$ sudo -
$ dnf install git -y
$ curl -OL https://raw.github.com/nvie/gitflow/develop/contrib/gitflow-installer.sh
$ chmod +x gitflow-installer.sh
$ ./gitflow-installer.sh
⚡ 4. 깃 플로우 전체 커멘드
$ git flow init # 초기화
$ git push origin --all # 업로드
$ git flow feature start <feature-branch> # feature 브랜치 시작
$ git flow feature list # featuire 브랜치 목록 확인
$ git add . # 파일 추적 시작
$ git commit -m
# push & pull-request(to review)
$ git flow feature finish <feature-branch> # 코드 리뷰 완료 후 develop 브랜치 머지
$ other-feature> git merge --no-ff develop # 다른 브랜치인 경우 해당 명령어 사용
$ git flow release start <tag>
$ git flow release finish <tag>
$ git tag
$ git push origin --all --follow-tags
$ git flow hotfix start <tag>
$ git flow hotfix finish <tag>
- release와 hotfix는 tag인 것을 유의하여야 합니다.
4-1. 시나리오 구성
Git Flow 시나리오
- 2개 feature 시작 (login, regist)
- login, regist 각각 코딩
- login 작업 완료
- login 코드 리뷰
- login 릴리즈 & 배포 (0.1.0)
- regist 작업 완료
- regist 릴리즈 (0.2.0) -> QA, TEST
- 0.1.0에서 버그 발생!! -> hotfix 시작
- hotfix 0.1.1 작업 완료
- hotfix 0.1.1 코드 리뷰
- hotfix 0.1.1 배포 (0.1.1)
- regist 릴리즈 마무리 & 배포 (0.2.0)
0(major).1(feature).0(minor)
⚡ 5. 깃 플로우 CLI 시작
$ git flow
usage: git flow <subcommand>
Available subcommands are:
init Initialize a new git repo with support for the branching model.
feature Manage your feature branches.
bugfix Manage your bugfix branches.
release Manage your release branches.
hotfix Manage your hotfix branches.
support Manage your support branches.
version Shows version information.
config Manage your git-flow configuration.
log Show log deviating from base branch.
Try 'git flow <subcommand> help' for details.
- git flow 커멘드를 통해 설치 여부를 확인해야 합니다.
5-1. 로컬 저장소 초기화
$ git flow init # 로컬 깃 저장소 초기화
Initialized empty Git repository in C:/funin-project/workspace-vscode/20220206_company_gitflow_seminar/git-flow-test/.git/
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master] # master 브랜치명
Branch name for "next release" development: [develop] # 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? [C:/funin-project/workspace-vscode/20220206_company_gitflow_seminar/git-flow-test/.git/hooks]
- 로컬 저장소를 초기화합니다.
- 브랜치명을 다르게 주고싶은 경우 해당 링크를 참고해주세요.
5-2. 생성된 모든 브랜치 확인
$ git branch -a # 모든 브랜치 확인
* develop
master
- (*) 현재 위치해 있는 브랜치를 표시합니다.
- git flow init를 통해 master, develop 브랜치가 생성된 상황입니다.
5-3. 원격 저장소와 로컬 저장소 연결
개발 상황에 따라 clone을 하여 프로젝트를 받아야 하는 경우도 있고 그렇지 않은 경우도 존재합니다.
현재는 깃헙에 레포지토리가 생성되되어 있다 가정하고 진행을 하겠습니다.
5-4. 로컬 저장소와 원격 저장소 연동
$ git remote add origin https://github.com/ym1085/test.git # github
$ git remote -v # 연결 확인
origin https://github.com/ym1085/test.git (fetch)
origin https://github.com/ym1085/test.git (push)
- 기존에 생성이 되어있는 원격지의 프로젝트와 연결합니다.
- 또한 git remote -v 명령어를 통해 원격지와 로컬 저장소의 연결 확인합니다.
5-5. 생성된 브랜치 원격지에 미리 업로드
$ git push orgin --all # 원격지에 생성된 브랜치 배포
Enumerating objects: 2, done.
Counting objects: 100% (2/2), done.
Writing objects: 100% (2/2), 164 bytes | 164.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/ym1085/test.git
* [new branch] develop -> develop
* [new branch] master -> master
원격지에 모든 브랜치가 업로드 되 있어야 다른 개발자들이 작업을 진행 할 수 있기에,
깃 플로우를 통해 생성 된 모든 브랜치를 서버에 업로드 합니다.
5-6. feature branch 시작
# git flow feature start <feature-branch>
$ git flow feature start login
...중략
$ git flow feature start register
Switched to a new branch 'feature/register'
Summary of actions:
- A new branch 'feature/register' was created, based on 'develop'
- You are now on branch 'feature/register'
Now, start committing on your feature. When done, use:
git flow feature finish register
$ git flow feature list
* feature-user-login
# 실제로는 지금보다 더 많은 feature 브랜치가 존재 할 수 있습니다.
# feature-user-join
# feature-user-payment
# feature-excel-upload
# feature-refactor-backend
- develop branch를 기반으로 login, register 브랜치를 생성합니다.
- 해당 브랜치 생성 후 두 번째 커멘드를 사용하여 생성된 브랜치를 확인합니다.
- Summary of actions를 체크 합니다.
5-7. login, register 브랜치 업로드
$ git push --all
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote: This repository moved. Please use the new location:
remote: https://github.com/ym1085/git-flow-sample.git
To https://github.com/ym1085/test.git
* [new branch] feature/login -> feature/login
* [new branch] feature/register -> feature/register
다른 개발자들 역시 해당 기능이 개발되고 있다는 것을 인지해야 하기 때문에,
위에서 생성한 login, register 브랜치를 업로드합니다.
⚡ 6. 로그인 기능 개발 시작
6-1 로그인 기능 작업
// login.js
const login = (userId) => {
if (userId !== "") {
console.log(`hello ${userId}`);
}
};
login("ymkim");
첫번째로 해당 함수를 추가하고 수정한 파일을 추적하고 원격지에 업로드 할 수 있는 방법을 알아보겠습니다.
6-2 add, commit, push
add
# add . 사용은 지양해야 한다. 가급적이면 수정한 파일의 경로를 정확히 명시한다.
$ git add userLogin.js
commit
# commit은 버전의 의미있는 변화를 등록하는 작업을 의미합니다.
# https://richone.tistory.com/26
$ git commit -m "Login start"
[feature/login a578922] Login start
1 file changed, 8 insertions(+)
create mode 100644 userLogin.js
push
# 코드 리뷰가 완료되면 pull-request를 종료합니다.
$ git push origin feature/login
⭐️ 6-3. 코드 리뷰 진행
6-3-1. 코드 리뷰 요청
- Reviewrs를 등록하고 pull request를 요청합니다.
6-3-2. pull request 버튼 클릭 후 화면
현재 Review required 탭을 보면, 하나 이상의 리뷰가 존재해야 병합이 가능하도록
설정 해두었기 때문에, 리뷰어(Reviwer)에게 리뷰를 받아야 합니다.
6-3-3. Reviewer의 화면
6-3-4. 코드 리뷰 메시지 작성
리뷰어는 요청자의 코드를 확인한 후 코드 리뷰 메시지를 작성합니다.
이 때 간단한 Comment, Approve, Request changes 옵션 중 하나를 선택하여
요청자에게 전달 할 수 있습니다.
6-3-5. 코드 리뷰 후 승인 화면
만약 코드의 이상이 없을 경우 리뷰어는 요청자의 pull request를 승인합니다.
후에 위 같은 화면을 볼 수 있습니다.
6-3-6. 코드 리뷰 완료 후 해당 브랜치 종료
$ git flow feature finish login
- 코드 리뷰가 완료되면 해당 명령어를 통해 feature branch를 종료한다.
- 위 명령어를 사용하게 되면 아래와 같이 자동으로 develop branch에 merge가 됩니다.
- 또한, 깃헙에 존재하는 Pull Request 역시 closed 됩니다.
06-4. 코드 리뷰가 완료 된 로그인 기능 회원가입 기능에 병합
# 브랜치 이동
$ git checkout feature/register
# login branch는 종료 되었기 때문에, develop 브랜치에서 변경 사항 merge
# --no-ff : non-fast-forward opt
$ git merge --no-ff develop
Merge made by the 'recursive' strategy.
userLogin.js | 10 ++++++++++
1 file changed, 10 insertions(+)
create mode 100644 userLogin.js
현재 혼자 버전 관리를 진행하고 있기 때문에 실무와는 차이가 있을 수 있습니다.
- 로그인 기능이 완료되었고, 회원가입 기능에 변경 사항을 적용 합니다.
06-5. release 브랜치 생성
$ git flow release start 0.1.0
Branches 'develop' and 'origin/develop' have diverged.
And local branch 'develop' is ahead of 'origin/develop'.
Switched to a new branch 'release/0.1.0'
Summary of actions:
- A new branch 'release/0.1.0' was created, based on 'develop'
- You are now on branch 'release/0.1.0'
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.1.0'
- register branch에서 release 브랜치를 0.1.0 버전으로 생성합니다.
06-6. release 브랜치 역시 원격지에 배포
# git push origin --all # regist, release 브랜치 동시에 push
$ git push origin release/0.1.0
Enumerating objects: 14, done.
Counting objects: 100% (14/14), done.
Delta compression using up to 8 threads
Compressing objects: 100% (9/9), done.
Writing objects: 100% (13/13), 1.32 KiB | 1.32 MiB/s, done.
Total 13 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), done.
remote:
remote: Create a pull request for 'release/0.1.0' on GitHub by visiting:
remote: https://github.com/ym1085/Gitflow-Practice-Final/pull/new/release/0.1.0
remote:
To https://github.com/ym1085/Gitflow-Practice-Final.git
* [new branch] release/0.1.0 -> release/0.1.0
06-7. 코드 리뷰
🚀 코드 리뷰의 경우 위에서 설명을 하였기에 간략히 설명 후 넘어가겠습니다.
- 코드 리뷰가 완료되고, 해당 브랜치를 종료합니다.
06-8. release 0.1.0 브랜치 종료
$ git flow release finish 0.1.0
- 버전을 입력하는 vi 창이 출력되고, 해당 창에 릴리즈 버전 입력.
$ git flow release finish 0.1.0
# 버전 입력 후
Branches 'develop' and 'origin/develop' have diverged.
And local branch 'develop' is ahead of 'origin/develop'.
Switched to branch 'master'
Merge made by the 'recursive' strategy.
README.md | 7 +++++++
login.py | 8 ++++++++
2 files changed, 15 insertions(+)
create mode 100644 README.md
create mode 100644 login.py
Already on 'master'
Switched to branch 'develop'
Merge made by the 'recursive' strategy.
README.md | 7 +++++++
1 file changed, 7 insertions(+)
create mode 100644 README.md
To https://github.com/ym1085/Gitflow-Practice-Final.git
- [deleted] release/0.1.0
Deleted branch release/0.1.0 (was 3f11307).
Summary of actions:
- Release branch 'release/0.1.0' has been merged into 'master'
- The release was tagged '0.1.0'
- Release tag '0.1.0' has been back-merged into 'develop'
- Release branch 'release/0.1.0' has been locally deleted; it has been remotely deleted from 'origin'
- You are now on branch 'develop'
06-9. 병합된 master, release 브랜치 원격지에 업로드
$ git push origin --all
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 8 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 630 bytes | 630.00 KiB/s, done.
Total 5 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/ym1085/Gitflow-Practice-Final.git
99c0ad2..f59703d develop -> develop
99c0ad2..0e62866 master -> master
06-4-1. 태그 생성
$ git push origin --all --follow-tags # 커밋과 태그를 동시에 푸시
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 153 bytes | 153.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/ym1085/Gitflow-Practice-Final.git
* [new tag] 0.1.0 -> 0.1.0
- 태그 추가시에는 위 명령어 입력.
⚡ 07. 회원가입 기능 개발 시작
직전에 개발중이던 회원 가입 기능 개발 다시 시작.
07-1. 회원 가입 기능 추가 및 완료
function regist() {
console.log(`regist complete`);
}
- 회원 가입 기능이 완료 되었다 가정.
💡 회원 가입의 토픽의 경우, 중복되는 내용을 중략하였습니다.
07-2. 핫픽스 브랜치 생성
회원가입 기능을 릴리즈 하여 코드 리뷰를 받고, master와 develop 브랜치에 병합하기 전에,
기존 완료가 되었던 로그인 기능에 이상이 있다 가정하고 진행.
$ git flow hotfix start 0.1.1
Switched to a new branch 'hotfix/0.1.1'
Summary of actions:
- A new branch 'hotfix/0.1.1' was created, based on 'master'
- You are now on branch 'hotfix/0.1.1'
Follow-up actions:
- Start committing your hot fixes
- Bump the version number now!
- When done, run:
git flow hotfix finish '0.1.1'
07-3. 핫픽스 브랜치 원격지에서 코드 리뷰
- 원격지에서 코드 리뷰를 받은 후에 해당 브랜치를 종료합니다.
07-4. 핫픽스 브랜치 종료
$ git flow hotfix finish 0.1.1
Switched to branch 'master'
Merge made by the 'recursive' strategy.
login.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
Switched to branch 'develop'
Your branch is up to date with 'origin/develop'.
Merge made by the 'recursive' strategy.
login.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
- [deleted] hotfix/0.1.1
Deleted branch hotfix/0.1.1 (was 142dc2c).
Summary of actions:
- Hotfix branch 'hotfix/0.1.1' has been merged into 'master'
- The hotfix was tagged '0.1.1'
- Hotfix tag '0.1.1' has been back-merged into 'develop'
- Hotfix branch 'hotfix/0.1.1' has been locally deleted; it has been remotely deleted from 'origin'
- You are now on branch 'develop'
07-5. 회원 가입 기능에 bug fix 내용 병합
$ git merge --no-ff develop
Merge made by the 'recursive' strategy.
login.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
07-6. 원격지에 배포
$ git push origin --all --follow-tags
Enumerating objects: 12, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 8 threads
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 911 bytes | 911.00 KiB/s, done.
Total 8 (delta 4), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (4/4), completed with 1 local object.
To https://github.com/ym1085/Gitflow-Practice-Final.git
be1485f..bd46e17 develop -> develop
0e62866..911e8a9 master -> master
be1485f..a71071d release/0.2.0 -> release/0.2.0
* [new tag] 0.1.1 -> 0.1.1
💡 Other Commands
$ git flow release start <tag> # release branch 생성
$ git flow release finish <tag> # release branch 종료
$ git tag # tag 생성
$ git push origin --all --follow-tags # 태그 + 커밋
$ git flow hotfix start <tag> # hotfix 생성
$ git flow hotfix finish <tag> # hotfix 종료
댓글남기기