티스토리 뷰

 

이번 글에서는 Git Flow Extension Library를 활용하여 보다 편리하게 git flow 브랜치 전략을 적용하는 방법에 대해 알아보고자 한다. (Git Flow에 대한 자세한 설명은 다음 글을 참고)

 

 

효율적인 깃 브랜치 전략 Git Flow - 1

협업 시 필수적인 깃을 효과적으로 사용하기 위해 다양한 깃 브랜치 전략이 존재한다. 그 중 팀의 규모가 크고 지속적인 개발&배포 사이클이 존재할 때 사용할 수 있는 Git Flow 전략에 대해 알아

daeun21dev.tistory.com

 

Git 명령어로 직접 git flow 전략을 구현할 수도 있지만 확장 라이브러리를 사용하면 간단한 1개의 명령어가 git flow를 위한 긴 여러 개의 명령어를 대신할 수 있다. 

 

 

설치

일단 git flow 확장 라이브러리를 사용하기 위해서는 기본적으로 git이 설치되어있어야 한다. 윈도우는 git 설치 시 git flow 또한 포함되어 설치되기 때문에 별도의 작업이 필요없다. 반면 MacOS는 git 설치 이후 brew install git-flow 명령어로 별도의 설치가 필요하다. (이 외 OS별 git flow 설치 방법은 링크 참고)

 

 

Git Flow 초기화 

git flow를 적용하고자 하는 저장소에서 git flow init 명령어를 입력하여 초기화하는 과정이 필요하다. 이때 git flow의 각 브랜치에 대한 Naming Convention을 설정해주어야 하는데, base branch는 브랜치 이름을 support branch는 브랜치 이름의 prefix를 직접 지정할 수 있다. 그러나 기본값을 권장하므로 계속 Enter를 입력하여 넘어간다. (+ main 브랜치의 version tag prefix도 지정 가능 ex. v1.0.0의 v가 version tag prefix)

*Base branch: main, develop

*Support branch: feature, release, hotfix

 

 

이때 -d 옵션을 추가하면 일일이 Enter를 입력해줄 필요 없이 알아서 기본값으로 초기화된다. git flow init은 git flow 관련 설정을 초기화하는 것이지 해당 레포지토리 내 기존 코드나 브랜치 등은 변경하지 않으며 기존 Git 명령어 또한 동일하게 사용할 수 있다.

git flow init 
git flow init -d //기본값 사용

git flow init 명령어

 

 

Git Flow 취소

개발 중 git flow 확장 라이브러리를 더이상 사용하고 싶지 않을 때에는 다음 명령어를 입력하여 git flow 관련 깃 설정 파일을 모두 삭제한다. 물론 git flow를 취소한다고 해서 기존 코드나 생성된 브랜치가 삭제되지는 않고 관련 설정 파일들만 삭제되어 git flow 명령어를 더이상 사용하지 못하게 되는 것 뿐이다. 이후 다시 git flow init 명령어로 재초기화하는 것 또한 가능하다. 

git config --remove-section "gitflow.path"
git config --remove-section "gitflow.prefix"
git config --remove-section "gitflow.branch"

 

 

 

이제 git flow를 사용할 준비가 모두 완료되었다. git flow 명령어로 만들어지는 support branch의 이름은 '<prefix>/<상세 이름>'의 형태이다. 이때 git flow init에서 브랜치 이름의 prefix 값을 별도로 지정하지 않았다면 기본값은 각각 feature, release, hotfix 이다. (ex. feature 브랜치의 prefix를 feat으로 지정한 경우 'feat/<상세 이름>' 형태로 생성)

 

주로 사용되는 git flow 명령어의 구성은 다음과 같다.

git flow [feature | release | hotfix] [start | finish | publish] (-옵션) <상세 이름>

뒤에서 자세히 살펴보겠지만 start는 해당 브랜치를 생성하는 작업을, finish는 해당 브랜치에서 개발 완료 후 base branch로 병합하는 작업을, publish는 협업 시 해당 브랜치를 원격 저장소로 push하는 작업을 수행한다.

<상세 이름>은 브랜치 이름의 /(슬래시) 뒷 부분을 지정한다. 보통 feature 브랜치에서는 구현하는 기능의 이름으로(ex. login), release나 hotfix 브랜치에서는 버전 번호로(ex. 1.0.0) 작성한다. (옵션은 선택 값으로 생략 가능하다.)

 

 

 

브랜치별 Git Flow 명령어 

feature 브랜치 생성 

develop 브랜치에서 분기되는 feature 브랜치는 다음 명령어로 생성되고 이후 해당 feature 브랜치로 checkout한다. 생성된 feature 브랜치의 이름은 'feature/<기능 이름>' 이다. 

git flow feature start <기능 이름>

 

 

즉 위 명령어 한 줄이 다음 3줄의 명령어와 완전히 동일하게 동작하는 것이다.

git checkout develop
git branch feature/<기능 이름>
git checkout feature/<기능 이름>

feature 브랜치 생성

 

 

feature 브랜치 기능 개발 완료 

기능 개발 완료 시, 해당 feature 브랜치를 develop 브랜치에 병합한 후 삭제해주어야 한다. 이러한 일련의 과정을 다음 명령어 한 줄로 수행할 수 있다. develop 브랜치에 병합 시 항상 병합 커밋을 생성하길 원한다면 --no-ff 옵션을 추가해준다. 협업 시에는 새로운 기능이 추가된 develop 브랜치를 다음 기능 개발을 이어가기 위해 원격 저장소에 push해준다.

git flow feature finish <기능 이름>
git flow feature finish --no-ff <기능 이름> //병합 커밋 항상 생성

git push origin develop

feature 브랜치&nbsp;develop 브랜치에 병합 후 삭제

 

 

그러나 협업 시 내가 개발한 기능을 바로 로컬에서 병합하는 경우는 드물다. 보통 GitHub에서 해당 기능에 대한 PR을 생성하고, 팀원에게 코드 리뷰 → 승인을 받으면 그때 해당 PR을 merge한다. 이 경우 git push --set-upstream origin feature/<기능 이름> 명령어로 원격 저장소에 코드를 공유하는데, 다음 git flow 명령어가 동일한 기능을 수행한다. 

git flow feature publish <브랜치 이름>

feature 브랜치 원격 저장소에 push

 

 

원격 저장소에 해당 feature 브랜치를 publish한 후 finish를 수행해도 동일하게 develop 브랜치에 병합되고 로컬 저장소의 해당 feature 브랜치는 삭제되며, 뿐만 아니라 원격 저장소의 해당 feature 브랜치도 자동으로 삭제해준다.

 

feature 브랜치 publish 후 finish

 

 

 

release 브랜치 생성 

개발이 어느 정도 완료되면 출시 준비를 위한 release 브랜치를 생성해야 한다. release 브랜치는 다음 명령어로 develop 브랜치로부터 분기되어 생성되고 해당 release 브랜치로 checkout한다. 생성된 브랜치 이름은 'release/<버전 번호>' 이다.

git flow release start 1.0.0

release 브랜치 생성

 

 

release 브랜치 출시 준비 완료

출시 준비가 완료되면 다음 명령어로 release 브랜치를 main, develop 브랜치에 병합한다. 이때 main 브랜치의 병합 커밋에 버전 태그가 붙게 되는데 커밋 메시지와 같은 태그 메시지를 작성해주어야 한다. (태그 메시지를 작성하지 않으면 fail이 발생할 수 있으므로 꼭 작성!) 따라서 finish 명령어 실행 시 vim과 같은 텍스트 에디터가 열리며 이곳에 태그 메시지를 작성해준다. 기존 commit 명령어와 동일하게 -m 옵션으로 태그 메시지를 다음과 같이 간단하게 지정할 수도 있다.

git flow release finish <버전 번호>
git flow release finish -m "태그 메시지" <버전 번호>

 

 

finish 명령어 실행 시 다음 순서로 작업이 진행된다. 

1. main 브랜치에 병합 

2. main 브랜치의 해당 병합 커밋에 'version tag prefix + <버전 번호>' 형식으로 태깅 

3. develop 브랜치에 병합 

4. 해당 release 브랜치 삭제 (publish되었다면 원격 저장소의 해당 release 브랜치도 삭제) 

 

 

참고로 git flow init에서 main 브랜치의 version tag prefix를 별도로 지정하지 않은 경우 아래 명령어로 prefix 재설정이 가능하다.

git flow config set versiontagprefix <prefix>

 

 

그러나 실제 git flow release finish 명령어를 수행해보면 해당 release 브랜치를 develop 브랜치에 바로 병합하는 것이 아닌, 먼저 main 브랜치로 release 브랜치를 병합 후 다시 main 브랜치를 develop 브랜치에 병합하는 식으로 진행된다. Git 버전 별로 동작 방식이 조금씩 다른게 아닌가 추측하는데 만약 release 브랜치를 develop 브랜치에 바로 병합하고자 한다면 git flow의 finish 명령어를 사용하지 않고 직접 git 명령어를 입력해주면 된다. 

 

release 브랜치 main, develop 브랜치에 병합 후 삭제

 

 

이후 협업 시에는 새로운 릴리즈가 포함된 main, develop 브랜치와 생성된 태그를 원격 저장소에 push 한다.

git push origin main <버전 태그 이름>
git push origin develop

 

 

release 브랜치 또한 바로 로컬에서 병합하지 않고 코드 리뷰 등을 위해 원격 저장소에 publish할 수 있다.

git flow release publish <버전 번호>

release 브랜치 원격 저장소에 push

 

 

 

hotfix 브랜치 생성 

다른 브랜치들과 마찬가지로 start 명령어로 hotfix 브랜치를 생성할 수 있으며 생성 후 해당 브랜치로 checkout 된다.

git flow hotfix start <버전 번호>

hotfix 브랜치 생성

 

 

 

hotfix 브랜치 오류 수정 완료

hotfix 브랜치 또한 finish, publish가 가능하며 finish 명령어로 진행되는 작업의 순서 또한 release 브랜치와 동일하다. 협업 시에는 finish 이후 다음 버전 개발을 위해 원격 저장소로 push 해준다.

git flow hotfix finish <버전 번호>

git push origin main <버전 태그 이름>
git push origin develop

hotfix 브랜치 main, develop 브랜치에 병합 후 삭제

 

 

git flow hotfix publish <버전 번호>

hotfix 브랜치 원격 저장소에 push

 

 

 

협업 시 Git Flow 명령어 사용

git flow 명령어에 대해 알아보면서 협업 시에는 이걸 어떻게 사용하지 라는 부분에 의문이 생겼다. git flow 명령어로 생성한 브랜치를 원격 저장소에 publish한 뒤 PR을 날려 GitHub에서 merge하는 경우에는 로컬 저장소, 원격 저장소의 해당 브랜치를 직접 삭제해야 하는 등 git flow 명령어를 사용하는 것이 딱히 의미가 없어지기 때문이다. 특히 release, hotfix 브랜치를 GitHub에서 merge하기 위해서는 main, develop 브랜치에 대한 PR을 총 2개 날려야 한다. 

 

 

확실하진 않지만 우아한 형제들 블로그 글을 참고한 결과 내가 내린 결론은 다음과 같다. feature, release, hotfix의 보다 큰 단위의 작업을 관리하는 주 브랜치(git flow에서는 support branch ex. 사용자 관련 기능을 개발하는 브랜치)에서 더 상세한 기능을 구현하는 보조 브랜치(ex. 사용자 관련 기능 중 레이아웃 작업 브랜치)로 브랜치 계층을 더 나누고, 이 보조 브랜치들은 GitHub에서 PR을 날려 코드 리뷰 → 승인 시 해당 support branch에 병합한다. 이후 support branch를 base branch에 병합하는 작업은 로컬에서 git flow 명령어로 실행 후 다시 원격 저장소로 push하는 것이 최선의 방법이지 않을까 생각한다.

 

 

예시를 들어보자면 아래 feature/user 브랜치는 주 브랜치, feature/user-layout 브랜치는 feature/user 브랜치로부터 분기한 보조 브랜치이다.  feature/user-layout → feature/user로 병합하는 작업은 GitHub에서 PR을 날려 진행되며 feature/user → develop으로 병합하는 작업은 로컬에서 git flow 명령어로 수행된다. 즉 feature/user 주 브랜치는 기능 개발 커밋을 직접 생성하는 것이 아닌, 보조 브랜치를 통합하여 관리하는 역할만을 수행하는 것이다.

[feature/user])$ git pull origin feature/user
[feature/user])$ git checkout -b feature/user-layout –track origin/feature/user-layout

//사용자 관련 기능 중 레이아웃 작업 완료
[feature/user-layout])$ git push origin feature/user-layout
//origin feature/user-layout → origin/feature/user에 대한 PR 생성하고 코드 리뷰 승인 후 merge

//사용자 관련 기능 개발 완료
[feature/user])$ git pull origin feature/user
[feature/user])$ git flow feature finish user //로컬 develop 브랜치에 병합 후 삭제

//새로운 기능 추가된 develop 브랜치 원격 저장소에 push
[develop])$ git push origin develop

 

 

개발에서 100% 정답은 없다고 git flow 또한 자신의 개발 상황에 맞게 적절히 변형하여 적용하는 것이 좋을 것 같다. 이외 더 자세한 git flow 명령어, 옵션 등은 다음을 참고

 

 

 

끝.

 

 

 

참고

https://medium.com/tensult/version-controlling-using-git-flow-tags-57b34c1d6a71

https://danielkummer.github.io/git-flow-cheatsheet/

 

'Git & GitHub' 카테고리의 다른 글

효율적인 깃 브랜치 전략 Git Flow - 1  (0) 2023.06.08
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/09   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함