git은 SCM (Source Code Management), 코드의 형상을 관리해주는 도구입니다.
그렇기에 변경점을 commit이라는 단위로 관리하는데,
commit의 흐름이 엉망이면 문제가 생겼을 때 빠르게 찾아 수정하기 어렵습니다.
또한, 협업 환경에서 코드의 분석이나 작업한 코드에 대한 추적에도 문제가 생기며
무엇보다 commit을 할 때마다 무수한 conflict의 환영이 반겨주기도 합니다.
본 문서의 작성 목적은, git flow를 도입하면서도 기존의 작업 기록을 보존하기 위해서 merge에 --no-ff 옵션을 적용하고자 하는 분들이 참조하실 수 있도록 공유하고자 함입니다.
git flow가 무엇인지를 직접 설명하기보다는, 많은 곳에서 설명할 때 사용하는 이미지로 축약하겠습니다.
약간의 설명을 추가하자면,
git flow란 branch 별로 각각의 목적과 양식을 규칙으로 정한 뒤,
그 규칙에 따른 commit history를 관리하는 것을 의미한다고 볼 수 있습니다.
(이미지 출처 - https://nvie.com/posts/a-successful-git-branching-model/)
본 문서의 git flow는 브랜치마다 각각의 규칙이 있으며,
rebase가 아닌 merge를 이용해 각자 작업한 커밋의 흐름을 정확히 파악할 수 있게 하는 것이 원칙입니다.
실제 이를 적용한 git history는 아래 이미지처럼 보일 것입니다.
(파란 것이 master, 핑크색이 release, 초록색이 dev, 그 외는 로컬에서 작업해 dev로 merge된 branch입니다).
#주의할 점은, master/release/dev로 merge를 할 때 --no-ff 옵션을 필히 사용해야 한다는 것입니다.
만약 --no-ff 옵션을 사용하지 않으면,
master와 release의 history가 전부 dev의 맨 윗 커밋과 동일한 위치가 되어 보기에 불편해질 수 있습니다.
기본적으로 소문자를 사용합니다.
본 문서에서는, 원격(origin)에서 사용할 branch들의 이름을
master / release / dev(develop) / hotfix 로 사용합니다.
실제 라이브 서버에 배포될 버전을 커밋 단위로 사용하는 브랜치입니다.
커밋 메세지 : 버전에 release를 추가하고, 태그를 넣습니다.
(ex - v1.1.0 release, v2.0.6 release 등의 커밋메세지 & v1.1.0, v2.0.6 등의 태그 달기)
배포 : Code Pipeline 또는 Jenkins의 CI 툴에 의해, 커밋을 통한 배포만 허용됩니다.
실 서비스와 직결되므로, repository 관리자만이 컨트롤할 수 있도록 안전하게 관리할 수 있도록 설정해줍니다.
AWS의 codecommit을 쓰는 경우, 특정 계정 외에는 IAM으로 branch에 대한 접근 권한을 제어해주면 좋습니다.
프로젝트 설정파일 : gradle을 사용할 경우,
build.gralde파일의 version을 항상 커밋메세지와 통일시켜줍니다.
(dev의 커밋을 통합한)** 버전을 커밋** 단위로 사용하는 브랜치입니다.
실제 라이브와 유사한 환경이며,
주로 QA를 하거나 라이브 배포 버전을 확인하는 것이 목적입니다.
커밋 메세지 : 버전으로 통일합니다. (ex - v1.1.0, v2.0.6 등)
라이브 서버에 빨리 적용해야 할 hotfix와 관련된 커밋만을 올리는 브랜치이며,
맨 위에 첨부한 사진처럼 관리를 하고 싶다면,
이 branch에 변경사항을 적용해서 커밋한 뒤 master와 dev에 각각 merge --no-ff 를 실행해줍니다.
**커밋 메세지 **: 커밋 타입만 hotfix로 고정해주시면 됩니다.
개발서버에서 작업한 변경사항이 커밋 단위로 적용되는 브랜치입니다.
작업이 완료되어 dev 브랜치에 커밋할 때,
dev에 그대로 올릴지와 분기한 브랜치에 올릴지는 상황에 따라 결정합니다.
커밋 메세지 : 명명 규칙만 지켜줍시다.
프로젝트 설정파일 : 필수는 아니지만, 릴리즈 버전 뒤나 첫 시작할 경우 version 뒤에 -snapshot 등을 붙여 릴리즈 버전과 구분하면 좋습니다.
ex) v0.0.1-snapshot
dev에서 분기하는 브랜치의 명명 규칙
'i-이슈번호' / '약어-이슈번호' 중 편한 것으로 합니다.
ex) i-463 / PAS-463
이는 해당 커밋이 jira의 어떤 issue와 연결이 되어있는지 빠르게 확인이 가능하도록 연결하기 위함입니다.
branch명은 본인이 편한대로 사용하되,
원격(origin)에 올릴 경우 작업이 끝나면 꼭 push --delete를 이용해 지웁니다.
ex)
git checkout dev
git merge --no-ff i463
git commit --amend
git branch -D i463
branch를 불문해서 적용하시길 바라며, 아래의 양식을 추천합니다.
jira 외의 툴로 일정을 관리한다면, [ ] 안에 들어갈 내용을 변경하시면 됩니다.
ex ) fix : 회원 정보 수정 API 정규식 변경 (PAS-463)
위와 같이 커밋 메세지는 해당 커밋에 대해 간략하면서도 핵심적인 설명을 써주도록 하며,
jira와 연동시 상세한 부분은 이슈에 적어줍니다.
PAS-463의 의미는, 약어가 PAS인 보드의 463 번 이슈와 연결되었음을 의미합니다.
이렇게 jira를 커밋 메세지에 연결하는 이유는,
해당 커밋이 jira의 어떤 issue와 연결이 되어있는지 빠르게 확인이 가능하도록 연결하기 위함입니다.
정해진 것이 아니며, 팀원들의 협의 하에 정하면 됩니다.
feat : 새로운 기능 추가
fix : 버그 수정
hotfix : 라이브 서버에 바로 적용해야 할 버그 수정
refac : 코드의 리팩토링 (코드의 기능 수정, 향상, 보완 등)
test : Test 관련한 코드의 추가, 수정
docs : 문서의 수정 (Javadoc 등)
style : (코드의 수정 없이) 스타일(style)만 변경(들여쓰기 같은 포맷이나 세미콜론을 빼먹은 경우)
chore : 기타
타입을 복수로 가지지 않는 이유는,
하나의 커밋에 복수의 목적이 담겼을 경우 차후에 파악하기 무척 어려워지기 때문입니다.
한글로 커밋에 대한 간략한 설명을 해주시면 됩니다.
ex) 정보 수정 API 파라미터 추가, dev 설정파일 변경 등
CLI 를 통한 개발 작업 순서 예시
a. dev 브랜치로 이동
$ git checkout dev
b. dev 브랜치를 origin(원격 저장소) 기준으로 갱신
$ git pull -r origin dev
dev 브랜치의 기준에서 pull을 하며 리베이스( -r, rebase) 옵션을 사용해,
origin의 dev 브랜치에 있는 HEAD 기준으로 코드를 갱신하는 것
(원하지 않는 로컬 커밋을 merge하지 않을 수 있음)
c. ** 작업할 브랜치로 분기 **
$ git checkout -b new_branch_name
ex) $ git checkout -b PAS-17
(jira를 사용하면서 보드명의 약자가 PAS, 이슈 번호가 17인 경우)
d. 새로운 branch에서 작업해서 커밋
e. 작업 완료
$ git checkout dev
$ git merge --no-ff 작업브랜치
$ git commit --amend (커밋 메세지 수정)
$ git push origin dev
다른 브랜치로 merge하고자 할 경우, ‘dev’에 해당하는 브랜치명을 수정하면 됩니다.
읽어주셔서 감사합니다 🙂