-이 글은 저희 팀에 Git Flow를 제안하며 작성한 제안서 입니다.-
Git Flow란?
- Git-flow는 Git이 활성화 되기 시작하던 10년 전 Vincent Driessen의 블로그 글에 의해 널리 퍼지기 시작했고, 현재는 개발 시 표준과도 같이 사용되는 방법입니다.
Git-flow 는 기능이 아닌 서로 간의 약속. 즉, 방법론이다.
Git Flow 이해하기!
보통 깃을 검색하면 많이 나오는 이미지 입니다.
사진의 이해를 돕기 위해 간략하게 설명하겠습니다.
Vincent Driessen의 브랜치 모델에는 5가지 종류가 있습니다.
- Master
정식 배포되는 안정적인 버전의 소스 코드 Master 브랜치의 HEAD는 최신 배포 버전의 소스 코드가 들어있습니다.
- Develop
개발 브랜치로 개발자들이 이 브랜치를 기준으로 각자 작업한 기능들을 합칩니다(Merge).
- Feature
단위 기능을 개발하는 브랜치로 기능 개발이 완료되면 develop 브랜치에 합칩니다.
- Release
배포를 위해 master 브랜치로 보내기 전에 먼저 QA(품질검사)를 하기위한 브랜치 입니다.
- Hotfix
master 브랜치로 배포를 했는데 버그가 생겼을 떄 긴급 수정하는 브랜치 입니다.
Git Flow 사용 방법은?
- Master(Main)에서 시작
- Master branch에서 Develop branch 생성
- 신규 개발 및 기능 수정이 필요한 경우 Develop branch에서 Feature branch 생성
- 기능 구현 후 Develop branch에 병합
(Feature branch에서 작업한 내용은 최종적으로 pull request → Develope branch에 병합) - Release branch는 develop branch 기반으로 생성
(다음 배포에 포함되어야 하는 기능들이 확정 된 후 생성) - Release branch 기준으로 QA 테스트 진행
이 과정에 발견된 버그 수정 사항들은 Release와 Develop branch에 적용 - Release branch의 코드가 안정적인 단계에 이르면 Master branch에 병합
이 모든 단계의 작업은 PR, QA등의 절차가 있습니다.
안정성 측면에서 장점이 있지만 긴급한 대응에는 오히려 걸림돌이 될 수 있습니다.
긴급한 대응을 필요로 하는 상황에선 아래와 같이 진행합니다.
Hotfix는 아래와 같이 진행한다.
- Master branch 기반으로Hotfix branch 생성
- 긴급 수정
- Master branch에 병합
- Develop branch에도 병합(이후 Release branch에도 반영 되도록)
그렇다면 지금의 우리의 상태는?
방식을 논하기 전 우리 팀의 현 상황을 리뷰 해보도록 하겠습니다.
우리의 현 상황
-(원래 개발자들의 실명으로 브랜치가 있지만, personal로 표기하였습니다.)-
처음 입사 했을 당시 Bitbucket을 단순한 코드 저장소(백업용)로만 사용하던 우리를 생각해 본다면,
Github로 버전 관리 및 협업을 하고 있는 지금, 많이 발전했고 또 성장 했다고 생각합니다.
지난 몇 달 쿠폰 및 예약플랫폼 연동과 같은 큰 규모의 신규 개발을 진행하며 5명의 백엔드 개발자 모두가 한 프로젝트의 코드를 수정해야 했습니다.
이 과정에서 누구는 Feature 브랜치를 생성하여 사용하기도 하고, 또 다른 누구눈 기존의 테스트 브랜치를 사용하기도 했습니다.
그러다 보니 최신의 코드를 유지하고 있는 브랜치가 계속 바뀌면서 어떤 기능의 브랜치는 branch1 기준으로 생성하고 또 어떤 브랜치는 branch2 기준으로 생성하여 사용 했습니다.
우리가 겪고 있는 어려움은? (제안 이유)
위와 같은 방식으로 사용하다 보니 branch를 병합해야 할 때 마다 다른 개발자가 수정한 코드를 보며 어떤 것이 수정 된 코드인지 판별하기가 어려웠습니다.
저희끼리 우스갯소리로 코딩보다 Git 관리가 더 어렵다고 할 정도로 Git branch 관리에 할애하는 시간 또한 많았습니다.
Git은 협업의 기본이며, 개발자들의 필수 역량이라고 합니다.
지금부터 우리 팀에 맞는 Git Flow 및 Git Convetion 만들어 사용한다면 업무 효율성도 높아지고 개인의 개발 역량 측면에서도 많은 도움이 될 것이라 생각합니다.
우리는 어떤 방식으로 사용하면 좋을까?
쉬운 코드 병합, 명확한 버전 관리 그리고 간단한 배포를 위하여 제안하는 Git Flow인 만큼
기존의 방식을 그대로 사용 하기 보다 최소한의 절차로 변형하여 사용하고자 합니다.
- Master를 기준으로 브랜치를 생성하여 기능 개발
(master) git checkout -b feature/change-station
- 작업 완료 후 Mater에 병합
(feature/change-station)git checkout master
(master)git merge feature/change-station
- 기능 테스트를 마친 후 Master를 배포 브랜치 생성
(master)git checkout -b release-1.0.2
(release-1.0.2)git commit -m ":sparkles: release: Change-station-name"
(release-1.0.2)git push origin release-1.0.2
- Release 브랜치까지 생성이 되면 기존의 Feature 브랜치 삭제
git branch -d feature/change-station-name
우리만의 git-commit-message-convention 📌
(사실 깃모지는 그냥 귀여워서 쓰고 싶습니다! 🙌)
Commit Message format
All Commit Message Format MUST meet this Text Format:
[:<Emoji>: ][<Type>[(<Scope>)]: ]<Subject>
ex) git commit -m ":sparkles: release: Change-station"
Emoji | Raw Emoji Code | Type | Description |
---|---|---|---|
⭐ | :star: |
new or feature |
add new feature |
🐛 | :bug: |
bug |
fix bug issue |
🚑 | :ambulance: |
bug |
critical hotfix bug issue |
🔒 | :lock: |
security |
fix security issue |
📈 | :chart_with_upwards_trend: |
performance |
fix performance issue |
⚡ | :zap: |
improvement |
update backwards-compatible feature |
💥 | :boom |
breaking |
update backwards-incompatible feature |
⚠️ | :warning: |
deprecated |
deprecate feature |
🌐 | :globe_with_meridians: |
i18n |
update or fix internationalization |
♿ | :wheelchair: |
a11y |
update or fix accessibility |
🚨 | :rotating_light: |
refactor |
remove linter/strict/deprecation warnings |
👕 | :shirt: |
refactor |
refactoring or code layouting |
✅ | :white_check_mark: |
test |
add tests, fix tests failur or CI building |
📝 | :pencil: |
docs |
update documentation |
©️ | :copyright: |
docs |
decide or change license |
🍭 | :lollipop: |
example |
for example or demo codes |
💄 | :lipstick: |
update |
update UI/Cosmetic |
🆙 | :up: |
update |
update other |
🚚 | :truck: |
update |
move or rename files, repository, ... |
🔀 | :twisted_rightwards_arrows: |
update |
merge conflict resolution |
➕ | :heavy_plus_sign: |
update |
add files, dependencies, ... |
➖ | :heavy_minus_sign: |
update |
remove files, dependencies, ... |
🔛 | :on: |
update |
enable feature and something ... |
⬆️ | :arrow_up: |
deps |
upgrade dependencies |
⬇️ | :arrow_down: |
deps |
downgrade dependencies |
📌 | :pushpin: |
deps |
pin dependencies |
🔧 | :wrench: |
config |
update configuration |
📦 | :package: |
build |
packaging or bundling or building |
🐳 | :whale: |
build |
Dockerfile |
🐣 | :hatching_chick: |
release |
initial commit |
🎊 | :confetti_ball: |
release |
release major version |
🎉 | :tada: |
release |
release minor version |
✨ | :sparkles: |
release |
release patch version |
🚀 | :rocket: |
release |
deploy to production enviroment |
🔖 | :bookmark: |
release |
tagged with version label |
🔙 | :back: |
revert |
revert commiting |
🚧 | :construction: |
wip |
WIP commiting |
Types
Type | Description |
---|---|
feature |
for new feature implementing commit |
update |
for update commit |
bug |
for bug fix commit |
security |
for security issue fix commit |
performance |
for performance issue fix commit |
improvement |
for backwards-compatible enhancement commit |
breaking |
for backwards-incompatible enhancement commit |
deprecated |
for deprecated feature commit |
i18n |
for i18n (internationalization) commit |
a11y |
for a11y (accessibility) commit |
refactor |
for refactoring commit |
docs |
for documentation commit |
example |
for example code commit |
test |
for testing commit |
deps |
for dependencies upgrading or downgrading commit |
config |
for configuration commit |
build |
for packaging or bundling commit |
release |
for publishing commit |
wip |
for work in progress commit |
chore |
for other operations commit |
If the prefix is the below types, it will appear in the changelog.
feature
bug
performance
security
improvement
deprecated
breaking
Scope
The scope could be anything specifying place or category of the commit change. For example $location, $browser, $compile, $rootScope, ngHref, ngClick, ngView, feature1, etc...