새로 이직한 회사에서 일반 Git이 아닌 Git-Flow라는 것을 권장 가이드라인으로 사용하고 있었다.
Git Flow? 읭. 내 머릿속의 git flow는 브랜치 전략, 병합 규칙 같은 흐름도 같은 게 전부였기에
gitflow 명령어와 기존 git 명령어의 차이점을 알아보기로 했다.
git-flow는 git과 별개의 존재가 아닌,
기존 git 명령어를 git-flow의 브랜치 전략을 자동화해 주는 트리거 같은 명령어 개념이다.
git-flow
Git 브랜치 전략을 자동화해 주는 도구
Vincent Driessen의 Git Flow 모델을 따름
앞에서 말한 git-flow의 브랜치 전략, 병합 규칙 같은 흐름도가 맞았던 것이다.
Gitflow 초기화
$ git flow init -d
해당 명령어를 통해 기본 설정(-d: defaults) 초기화가 가능하다.
이렇게 flow 정책을 세팅할 수 있는데, 정확히 저 명령어가 뭘 하는 거냐?
기본 설정이 아닌 (-d 없이) git flow init를 실행시킬 경우,
어떤 브랜치를 main으로 쓸지, develop 브랜치 이름은 뭘로 할지, prefix는 뭘로 할지에 대해 하나하나 지정할 수 있다.
Branch name for production releases: [master]
Branch name for "next release" development: [develop]
Feature branches? [feature/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []
기본 설정은 이 세팅을 일반적인 브랜치 이름으로 지정하는 것이다.
- Production branch → master (또는 main, 저장소 기본 브랜치 따라감)
- Development branch → develop
- Prefix
- feature → feature/
- release → release/
- hotfix → hotfix/
- support → support/
- Tag prefix → 없음("")
이렇게 초기화를 진행하면, 다음에 사용할 git flow에 대한 명령어에 대한 규칙이 세팅되는 것이다.
간단히 말하면, git flow init은 어느 브랜치에서 시작할지, 브랜치 이름 규칙을 지정할 수 있는 것이다.
다음은 많이 사용하는 git flow 명령어이다.
$ git flow <feature | release | hotfix> <start | finish> <branch_name>
git flow <feature | release | hofix> start 브랜치명
우선 start 명령어부터 살펴보도록 하자.
start는 명령어는 브랜치를 생성하는 명령어이다.
정확히는 내부적으로 flow에 저장된 target 브랜치에서 브랜치를 만들고, 해당 브랜치(만들어진)로 chackout 하는 것이다.
그렇다면 기본 설정(-d)으로 초기화된 gitflow에 대한 각각의 명령어의 실제 작업되는 git 동작으로 살펴보면 다음과 같다.
git flow feature start 브랜치명
- 출발(base): develop
- 브랜치명: feature/브랜치명
git checkout develop
git checkout -b feature/브랜치명 develop
git flow release start 버전명
- 출발(base): develop
- 브랜치명: release/버전명
git checkout develop
git checkout -b release/버전명 develop
git flow hotfix start 브랜치명
- 출발(base): main(또는 master)
- 브랜치명: hotfix/브랜치명
git checkout main
git checkout -b hotfix/브랜치명 main
이렇게 git flow를 사용하면 하나의 명령어를 통해 어떤 브랜치에서 어떤 브랜치를 만들어 해당 브랜치의 checkout까지 자동으로 실행시켜 주는 편-리함을 볼 수 있다.
git flow <feature | release | hofix> finsh 브랜치명
finsh 명령어는 start로 만들어진 브랜치에서 작업을 맞치고 머지하는 과정 즉, 마무리 작업을 자동화하는 명령어이다.
간단하게 실제 git 동작과 함께 살펴보자.
git flow feature finish 브랜치명
- 머지 대상: develop
- 동작:
- 현재 작업 중인 feature 브랜치를 develop에 --no-ff로 머지
- feature 브랜치 삭제
git checkout develop
git merge --no-ff feature/브랜치명
git branch -d feature/브랜치명
여기서 --no-ff는 (non fast-forward)로, merge 대상과 fast-forward 관계여도 강제로 merge commit을 생성하고 병합하는 것(기본 머지)을 뜻한다. 저번에 정리한 merge에 대해서 살펴보자.
https://androidhelper.tistory.com/35
[Git] Git Merge 종류 (with. force push로 commit이 사라졌을 경우)
작업을 하거나 협업을 할 때 브랜치를 만들고 해당 브랜치를 Merge 한 경험은 다들 있을 것이다.회사에서 Feather 브랜치를 만들고 delvop 같은 브랜치에 merge 하여 자신이 한 작업물을 올리는 등의 각
androidhelper.tistory.com
git flow release finish 버전명
- 머지 대상: main(또는 master), develop
- 동작:
- release/버전명을 main에 머지
- 해당 커밋에 버전 태그 생성 (예: v1.0.0)
- release/버전명을 develop에도 머지 (develop과 main 싱크 맞춤)
- release 브랜치 삭제
git checkout main
git merge --no-ff release/버전명
git tag -a 버전명 -m "Release 버전명"
git checkout develop
git merge --no-ff release/버전명
git branch -d release/버전명
feature 때와는 다르게 2개의 브랜치를 대상으로 merge를 진행하는데,
main에 새 버전 배포, develop도 최신 상태 유지하기 위한 명령어이기 때문이다.
git flow hotfix finish 브랜치명
- 머지 대상: main(또는 master), develop
- 동작:
- hotfix/브랜치명을 main에 머지
- 해당 커밋에 버전 태그 생성
- hotfix/브랜치명을 develop에도 머지
- hotfix 브랜치 삭제
git checkout main
git merge --no-ff hotfix/브랜치명
git tag -a 버전명 -m "Hotfix 버전명"
git checkout develop
git merge --no-ff hotfix/브랜치명
git branch -d hotfix/브랜치명
해당 명령어도 main에 긴급 패치 반영 + develop도 동일 코드 반영하기 위해 2개의 브랜치를 대상으로 하는 것을 확인할 수 있다.
정리하면 다음과 같다.
- feature = develop에 합치고 브랜치 삭제
- release = main + develop에 합치고 버전 태그 찍고 브랜치 삭제
- hotfix = main + develop에 합치고 버전 태그 찍고 브랜치 삭제
finish 명령어 | Merge 대상 | 태그 생성 | 브랜치 삭제 | 목적 |
feature finish | develop | X | O | 기능 개발 종료 |
release finish | main + develop | O | O | 배포 준비 완료 & 버전 태그 |
hotfix finish | main + develop | O | O | 긴급 수정 반영 & 버전 태그 |
이렇게 보니 의문이 든다.
음. 그러면 featrue로 start한 브랜치를 release로 finish 하면 어떻게 되는 거지?
즉, start와 finish의 짝이 맞지 않으면 어떻게 되는 거지?
결론부터 말하자면 동작하지 않는다.
git flow <feature | release | hofix> 해당 명령어에서 <>는 해당 브랜치의 폴더를 target으로 하기 때문이다.
그렇기 때문에 featrue start로 만든 브랜치는 feature/브랜치명에 브랜치가 만들어지며,
release finish를 실행할 때는 release/브랜치명을 기대하기 때문이다.
반대로 git flow feature start 브랜치명으로 만들지 않은 feature/브랜치명을
git flow feature finish 브랜치명은 정상적으로 기대하는 동작을 실행시킨다.
짜잔~
참고로 git flow 명령어에서 사용하는 push 명령은 다음과 같다.
git flow feature publish <브랜치명>
- 현재 브랜치가 feature/브랜치명인지 확인 (아니면 checkout)
- 원격(origin)에 feature/브랜치명 브랜치를 push
(-u 옵션 포함 → 추후 git pull / git push 기본 대상이 이 브랜치로 설정됨)
git push -u origin feature/브랜치명
실제 git 동작은 다음 명령어와 동일하게 동작한다.
feature start → feature publish → feature finish
마지막 꿀팁(?)으로, git flow를 사용 후,
git reflog를 통해 기록을 보면 내부적으로 일어난 "실제 명령어" 기준으로 history가 남아있다.
git은 짱이다.
'Android > 학습' 카테고리의 다른 글
[Git] Git Merge 종류 (with. force push로 commit이 사라졌을 경우) (8) | 2025.08.09 |
---|---|
[Android] LiveData란 (vs StateFlow) (6) | 2025.07.19 |
[Kotlin] Coroutine Flow란, 그리고 Flow, StateFlow, SharedFlow.. (9) | 2025.07.06 |
[CS] 동기 vs 비동기, 블로킹 vs 논블로킹, 그리고.. (1) | 2025.06.14 |
[Android] RecyclerView의 동작 과정 (5) | 2025.05.16 |