사용자 도구

사이트 도구


git:garam

Garam에서의 git 소스관리 방안

Branch 관리분류

  • master - 현재배포판
  • develop - 개발을 위한
  • release - 배포를 위한
  • feature - 기능구현을 위한
  • hotfix - 긴급패치판, master에 적용, develop에 적용

Merge

  • git merge –ff [branch] : Fast Forward
  • git merge –no-ff [branch] : Non Fast Forward
  • git merge –squash [branch] :

git merge --ff

–ff (fast-forward) 옵션은 현 브랜치와 merge 대상 브랜치가 fast-forward 관계에 있는 경우 새로운 commit을 생성하지 않고 브랜치의 참조 값만 변경되도록 한다. fast-forward 관계가 아니면 merge commit을 생성한다.

git merge --ff [브랜치명]

git merge --no-ff

–no-ff (non fast-forward) 옵션은 merge 대상과 fast-forward 관계여도 강제로 merge commit을 생성하고 병합한다.

master 브랜치에서 –no-ff 옵션으로 merge를 실행해보자.

git merge --no-ff [브랜치명]

merge --squash

–no-ff 옵션으로 merging을 하면 어떤 조건에서도 상대 브랜치의 commit 이력을 남기지 않는다. 하지만 git log –graph 명령 등을 통해 어떤 브랜치로 부터 merging 되었는지는 확인 할 수 있었다. –squash 옵션은 사전적 의미(짓 뭉개다)에서 알 수 있듯이 강압적인(?) 병합 방법이다. commit이력과 merge된 브랜치 이력도 남기지 않는다. 새로운 commit에 상대 브랜치의 내용을 모두 뭉쳐 놓은 것으로 보인다.

git merge --squash [브랜치명]

master branch

제품(product)출시를 위한 branch 배포(Release) 이력을 관리하기 위해 사용. 즉, 배포 가능한 상태만을 관리한다.

  1. version과 배포를 위해서 사용.
  2. release브랜치가 완성되면 master와 debelop에 머지
  3. hotfix/fix-xxxx를 master에서 생성하여

release branch

이번 출시 버전을 준비하는 브랜치

배포를 위한 전용 브랜치를 사용함으로써 한 팀이 해당 배포를 준비하는 동안 다른 팀은 다음 배포를 위한 기능 개발을 계속할 수 있다. 즉, 딱딱 끊어지는 개발 단계를 정의하기에 아주 좋다. 예를 들어, ‘이번 주에 버전 1.3 배포를 목표로 한다!’라고 팀 구성원들과 쉽게 소통하고 합의할 수 있다는 말이다.

  1. develop브랜치에서 생성하여 작업
  2. 명칭은 명확하게 release/YYYYMMDD, release/<version>, release/<스프린트명>
  3. release 브랜치에서 QA를 진행 완료 후 배포를 하게 된다.
// release 브랜치(release/1.2)'develop' 브랜치('master' 브랜치에서 따는 것이 아니다!)에서 분기
$ git checkout -b release/1.2 develop
 
/* ~ 배포 사이클이 시작 ~ */
 
/* release 브랜치에서 배포 가능한 상태가 되면 */
// 'master' 브랜치로 이동한다.
$ git checkout master
// 'master' 브랜치에 release/1.2 브랜치 내용을 병합(merge)한다.
# --no-ff 옵션: 위의 추가 설명 참고
$ git merge --no-ff release/1.2
// 병합한 커밋에 Release 버전 태그를 부여한다.
$ git tag -a 1.2
 
/* 'release' 브랜치의 변경 사항을 'develop' 브랜치에도 적용 */
// 'develop' 브랜치로 이동한다.
$ git checkout develop
// 'develop' 브랜치에 release/1.2 브랜치 내용을 병합(merge)한다.
$ git merge --no-ff release/1.2
// -d 옵션: release/1.2에 해당하는 브랜치를 삭제한다.
$ git branch -d release/1.2

develop branch

기능 개발을 위한 브랜치들을 병합하기 위해 사용. 즉, 모든 기능이 추가되고 버그가 수정되어 배포 가능한 안정적인 상태라면 develop 브랜치를 release브랜치로 분기하여, 출시준비를 한다. 평소에는 이 브랜치를 기반으로 개발을 진행한다.

  1. 개발을 위한 브랜치
  2. release가 배포되면 master와 develop에 머지
  3. feature 머지
  4. hotfix 머지

feature branch

기능을 개발하는 브랜치 feature 브랜치는 새로운 기능 개발 및 버그 수정이 필요할 때마다 ‘develop’ 브랜치로부터 분기한다. feature 브랜치에서의 작업은 기본적으로 공유할 필요가 없기 때문에, 자신의 로컬 저장소에서 관리한다. 개발이 완료되면 ‘develop’ 브랜치로 병합(merge)하여 다른 사람들과 공유한다.

  1. develop브랜치에서 생성
  2. 기능단위로 되도록 작게
  3. 완료되면 develop에 머지
// feature 브랜치(feature/login)'develop' 브랜치('master' 브랜치에서 따는 것이 아니다!)에서 분기
$ git checkout -b feature/login develop
 
/* ~ 새로운 기능에 대한 작업 수행 ~ */
 
/* feature 브랜치에서 모든 작업이 끝나면 */
// 'develop' 브랜치로 이동한다.
$ git checkout develop
// 'develop' 브랜치에 feature/login 브랜치 내용을 병합(merge)한다.
# --no-ff 옵션: 아래에 추가 설명
$ git merge --no-ff feature/login
// -d 옵션: feature/login에 해당하는 브랜치를 삭제한다.
$ git branch -d feature/login
// 'develop' 브랜치를 원격 중앙 저장소에 올린다.
$ git push origin develop

hotfix branch

출시 버전에서 발생한 버그를 수정 하는 브랜치. hotfix/fix-xxxxx 배포한 버전에 긴급하게 수정을 해야 할 필요가 있을 경우, ‘master’ 브랜치에서 분기하는 브랜치이다. ‘develop’ 브랜치에서 문제가 되는 부분을 수정하여 배포 가능한 버전을 만들기에는 시간도 많이 소요되고 안정성을 보장하기도 어려우므로 바로 배포가 가능한 ‘master’ 브랜치에서 직접 브랜치를 만들어 필요한 부분만을 수정한 후 다시 ‘master’브랜치에 병합하여 이를 배포해야 하는 것이다.

// release 브랜치(hotfix/fix-1.2.1)'master' 브랜치(유일!)에서 분기
$ git checkout -b hotfix/fix-1.2.1 master
 
/* ~ 문제가 되는 부분만을 빠르게 수정 ~ */
 
/* 필요한 부분을 수정한 후 */
// 'master' 브랜치로 이동한다.
$ git checkout master
// 'master' 브랜치에 hotfix/fix-1.2.1 브랜치 내용을 병합(merge)한다.
$ git merge --no-ff hotfix/fix-1.2.1
// 병합한 커밋에 새로운 버전 이름으로 태그를 부여한다.
$ git tag -a 1.2.1
 
/* 'hotfix' 브랜치의 변경 사항을 'develop' 브랜치에도 적용 */
// 'develop' 브랜치로 이동한다.
$ git checkout develop
// 'develop' 브랜치에 hotfix/fix-1.2.1 브랜치 내용을 병합(merge)한다.
$ git merge --no-ff hotfix/fix-1.2.1

예외 상황일 때 대응 사례

소프트웨어는 이해관계자가 다수 연결되어 항상 아름다운 방향으로만 흐르지 않는다. 흔히 발생하는 형상관리 이슈는 feature 브랜치를 작업할 때 빈번하게 발생한다. feature 브랜치 전략에 대한 경험적인 내용과 급히 기능 추가에 대한 경험을 작성한 부분이다.

* 병합 중에 충돌 발생한 사례

충돌은 feature 브랜치를 develop 브랜치에 병합을 할 때 발생할 확률이 높다. 충돌이 발생하면 develop 브랜치를 feature 브랜치에 병합한다. 병합 시에는 발생한 충돌 사항들 중 동료와 연관있는 기능이라면 꼭 페어 체크를 해야 한다.

충돌을 수정완료 한 뒤에는 다시 feature 브랜치를 develop 브랜치에 병합하면 완료된다.

* Pull Request 중인 브랜치에 작업한 사례

이 상황은 실수로 PR(Pull Request) 중인 브랜치로 작업을 하는 경우이다. 이때 PR 중인 브랜치를 기준으로 브랜치를 생성하는 선택을 하면 안 된다. PR이 완료되어 브랜치를 삭제하면 연관된 브랜치도 삭제되기 때문이다.

이 경우를 해결하기 위해서는 먼저 feature 브랜치를 develop 브랜치로부터 만든다. 그리고 생성한 feature 브랜치에 필요한 내용만 cherry-pick하여 가져가면 해결된다.

* 예정된 배포 일정 앞에 기능 배포한 사례

이 상황은 신규 기능 개발은 급하게 필요하지만, develop에 반영되어있던 기능들이 production에 배포하면 안 되는 사항이 있을 때다.

이 상황은 hotfix 전략으로 해결할 수 있다. 먼저 hotfix/YYYYMMDD로 hotfix+develop 역할의 핫픽스 개발 브랜치를 생성한다. hotfix 처럼 개발완료 시 master-develop에 병합되고, develop 처럼 feature를 만들어 병합할 수 있는 역할의 브랜치이다. 그리고 hotfix/YYYYMMDD를 기준으로 기능별로 브랜치를 만들어서 작업한다. 해당 브랜치도 핫픽스의 의미를 내포하여 hotfix라는 접두사를 붙여 작명을 한다.

그리고 hotfix/YYYYMMDD를 기준으로 기능별로 브랜치를 만들어서 작업한다. 해당 브랜치도 핫픽스의 의미를 내포하여 hotfix라는 접두사를 붙여 작명을 한다.

각 기능의 PR은 hotfix/YYYYMMDD에 진행을 한다. 개발 완료 후 내부 테스트가 필요하면 Sandbox에 배포 시 hotfix/YYYYMMDD로 배포를 한다.

테스트 완료 후 master/develop에 머지를 진행한다. production 배포는 기존 프로세스와 같이 master로 진행한다. 이렇게 되면 깃플로우 정책을 해치지 않고 작업이 가능하다.

이 솔루션을 알기 전까지는 배포하는 부분에서 고민했다. develop/master를 통해서만 배포를 해야 한다는 생각을 가졌는데, 이러한 상황에서는 유연하게 hotfix와 master로 배포하는 것으로 정리하면 유연하게 대응 가능하다고 판단했다.

git/garam.txt · 마지막으로 수정됨: 2025/04/15 10:05 저자 127.0.0.1