[번역] 성공적인 Git 분기 모델 > Git

Git

[번역] 성공적인 Git 분기 모델 정보

[번역] 성공적인 Git 분기 모델

본문

보통 Git를 사용해서 소스코드 관리를 할 때에는  혼자인 경우에는 간단하게 branch, merge등을 이용하면 될 것 같은데

 

여럿이 협업을 할때에는 어떻게 하는지 궁금해서 구글을 해 봤습니다.

 

https://nvie.com/posts/a-successful-git-branching-model/

 

A successful Git branching model

이 게시물에는 1년 전 (직장과 개인에서) 제 프로젝트를 위해 소개한 개발 모델을 소개했는데, 그 발전 모델이 매우 성공적이었습니다.  나는 잠시 동안 그것에 대해 글을 쓰고 싶었지만, 지금까지 철저히 그렇게 할 시간을 찾지 못했습니다. 프로젝트의 세부 사항에 대해서는 말하지 않고 단순히 분기 전략 및 릴리스 관리에 관해서는 설명하지 않겠습니다.

203892234_1549987077.6482.png

Why git? 

중앙 집중식 소스 코드 제어 시스템과 비교하여 Git의 장단점에 대한 자세한 설명은 웹을 참조하십시오.거기에 많은 불꽃 전쟁이 일어나고 있습니다. 개발자로서 나는 다른 도구들보다 위의 Git를 선호합니다. Git은 개발자가 병합과 분기를 생각하는 방식을 정말로 바꿔 놓았습니다. 내가 사용한 고전적인 CVS/Subversion 세계에서, 병합/분기는 항상 약간의 무서운 것으로 간주되었습니다 ( "병합 충돌에주의하십시오. 여러분을 괴롭힐 것입니다!").

그러나 Git을 사용하면 이러한 작업이 매우 저렴하고 간단하며 매일 작업 흐름의 핵심 부분중 하나로 간주됩니다. 예를 들어, CVS/Subversion 서적에서, 분기와 병합은 나중 챕터(고급 사용자 용)에서 논의되지만, 모든 Git 책에서는 3장 (기본)에서 이미 다뤘습니다.

단순성과 반복성의 결과로, 분기 및 병합은 더 이상 두려워 할 사항이 아닙니다. 버전 제어 도구는 다른 어떤 것보다 더 많이 분기/병합하는 것을 돕기로 되어 있습니다.

도구에 대해서는 그만 두고, 개발 모델로 나아가 봅시다. 여기서 제시할 모델은 기본적으로 관리되는 소프트웨어 개발 프로세스를 수행하기 위해 모든 팀 구성원이 따라야하는 일련의 절차입니다.

Decentralized but centralized

우리가 사용하고이 분기 모델에서 잘 작동하는 저장소 설정은 중앙의 "truth"저장소가있는 저장소 설정입니다. 이 저장소는 중앙 저장소로만 간주됩니다 (Git는 DVCS이므로 기술 수준에서는 중앙 저장소와 같은 것이 없습니다). 이 이름은 모든 Git 사용자에게 친숙하기 때문에이 repo를 origin이라고합니다.

203892234_1549987103.6328.png

 

각 개발자는 origin으로 푸시와 풀을 합니다. 그러나 중앙 집중식 푸시-풀 관계 외에도 각 개발자는 다른 동료의 변경 사항을 끌어와 하위 팀을 구성 할 수도 있습니다. 예를 들어, 진행중인 작업을 너무 일찍 시작하기 전에 둘 이상의 개발자가 큰 새로운 기능을 사용하여 작업하는 것이 유용할 수 있습니다. 위의 그림에는 Alice와 Bob, Alice와 David, Clair와 David의 하위 팀이 있습니다.

기술적으로 이것은 Alice가 Bob의 저장소를 가리키는 bob이라는 리모컨을 정의했고 그 반대의 경우도 마찬가지입니다.

The main branches 

핵심적으로, 개발 모델은 기존 모델의 영향을 크게받습니다. 중앙 repo에는 무한한 일생을 가진 2개 주요 분기가 있습니다:

  • master (마스터)
  • develop (개발)

원래의 마스터 분기는 모든 Git 사용자에게 친숙해야한다. 마스터 분기와 병행하여 개발이라는 또 다른 분기가 있습니다.

 

origin/master는 HEAD의 소스 코드가 항상 생산 준비 상태를 반영하는 주요 분기라고 생각합니다.

203892234_1549987441.8563.png

origin/development가 HEAD의 소스 코드가 항상 다음 릴리스의 개발 변경 사항을 제공한 상태를 반영하는 주요 분기라고 생각합니다. 일부는 이를 "통합 지점"이라고 부릅니다. 자동 야간 빌드가 구축되는 곳입니다.

 

개발 브랜치의 소스 코드가 안정 지점에 도달하여 출시 준비가되면 모든 변경 사항이 어떻게든 마스터에 다시 병합되어야 하며 릴리스 번호로 태그가 지정되어야 합니다. 이것이 어떻게 상세히 이루어질 지에 대해서는 계속 논의 될 것입니다.

 

따라서 변경 사항이 마스터로 다시 병합될 때마다 정의에 따라 새로운 프로덕션 릴리스입니다. 우리는 이론적으로 마스터에 커밋이 있을 때마다 Git 훅 스크립트를 사용하여 소프트웨어를 프로덕션 서버에 자동으로 빌드하고 롤아웃 할 수 있습니다.

Supporting branches 

주요 분기인 Master와 Development의 개발 모델은 팀 구성원 간의 병렬 개발을 돕고, 기능 추적을 용이하게 하며, 프로덕션 릴리스를 준비하고, 실시간 프로덕션 문제를 신속하게 수정하는 데 도움을주기 위해 다양한 지원 지점을 사용합니다. 주 분기와 달리 이 분기들은 결국 제거되기 때문에 항상 수명이 제한됩니다.

 

우리가 사용할 수있는 분기의 종류는 다음과 같습니다.

  • Feature branches
  • Release branches
  • Hotfix branches

각 분기는 특정 목적을 가지고 있으며 어떤 분기가 원래 분기인지, 어떤 분기가 병합 대상이어야하는지에 대한 엄격한 규칙에 따릅니다. 우리는 잠시 후에 그들을 다룰 것입니다.

기술적인 측면에서 볼 때 이러한 분기는 "특별"하지 않습니다. 지점 유형은 사용 방법에 따라 분류됩니다.  그들은 당연히 평범하고 오래된 Git 분기입니다.

Feature branches 

다음으로부터 분기 할 수 있습니다:
    develop
다시 병합해야합니다:
    develop
분기 명명 규칙:
master, develop, release-* 또는 hotfix-*를 제외한 모든 것.


기능(feature) 분기 (또는 때로는 주제(topic) 분기라고 함)는 향후 또는 향후 출시를 위한 새로운 기능을 개발하는 데 사용됩니다. 기능(feature) 개발을 시작할 때 이 기능(feature)이 통합되는 대상 릴리스는 그 시점에서 잘 알려지지 않을 수 있습니다. 기능(feature)의 본질은 기능(feature)이 개발되는 한 존재하지만, 결국에는 곧 출시 될 릴리스에 새로운 기능(feature)을 추가하기 위해 develop로 병합되거나 실망스러운 실험의 경우 폐기될 것입니다.

 

기능(feature) 분기는 일반적으로 개발자 repos에서만 존재하며 원본(origin)을 사용하지 않습니다.

 

203892234_1549988379.5773.png

Creating a feature branch

새 기능에 대한 작업을 시작할 때는 개발 브랜치에서 분기하십시오.

$ git checkout -b myfeature develop
Switched to a new branch "myfeature"

Incorporating a finished feature on develop 

완성 된 기능을 개발 분기에 병합하여 다음 릴리스에 확실히 추가 할 수 있습니다.

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop

--no-ff 플래그는 병합이 빨리 감기와 함께 수행 될 수 있는 경우에도 항상 새 커밋 객체를 작성하도록 합니다. 이렇게하면 기능 분기의 히스토리 존재에 대한 정보를 잃지 않고 기능을 추가 한 모든 커밋을 함께 그룹화 할 수 있습니다. 비교:

 

203892234_1549988604.8142.png

후자의 경우, Git 히스토리에서 커밋 객체 중 어떤 객체가 기능을 구현했는지를 볼 수 없습니다. 수동으로 모든 로그 메시지를 읽어야 합니다. 후자의 경우에는 전체 기능 (즉, 커밋 그룹)을 되돌리기가 쉽지 만 --no-ff 플래그가 사용되면 쉽게 완료됩니다.

 

네, 몇 가지 (빈) 커밋 객체를 만들지 만 그 이득은 비용보다 훨씬 큽니다.

Release branches 

다음으로부터 분기 할 수 있습니다 :
    develop
다시 병합해야합니다.
    develop 과 master
분기 명명 규칙 :
    release-*

 

릴리스 분기는 새로운 프로덕션 릴리스의 준비를 지원합니다. 그들은 내가 마지막 순간에 도트를 찍을 수 있게 해줍니다. 또한, 버그 수정 및 릴리스용 메타 데이터 (버전 번호, 빌드 날짜 등)를 준비할 수 있습니다. 릴리스 분기에서 이 모든 작업을 수행하면 개발 분기가 다음 큰 릴리즈의 기능을 수신하도록 지워집니다.

 

새 릴리스 분기를 개발에서 분기하는 주요 순간은 새 릴리스의 원하는 상태를 개발(거의)하는 시기입니다. 최소한 출시 예정 버전을 대상으로 하는 모든 기능을 병합하여 이 시점에 개발해야합니다. 이후 릴리스를 대상으로 하는 모든 기능은 릴리스 분기가 분기된 후에야 기다려야 합니다.

 

다가오는 릴리스에 버전 번호가 할당되는 것은 릴리스 분기의 시작 시점입니다. 그 시점까지 개발 브랜치는 "다음 릴리스"에 대한 변경 사항을 반영했지만 릴리스 브랜치가 시작될 때까지 "다음 릴리스"가 결국 0.3 또는 1.0이 될지 여부는 불분명합니다. 이 결정은 릴리스 분기 시작일에 이루어지며 버전 번호 범핑에 대한 프로젝트의 규칙에 따라 수행됩니다.

Creating a release branch 

릴리스 분기는 개발 분기에서 생성됩니다. 예를 들어, 1.1.5 버전이 현재 프로덕션 릴리스이고 우리에게 큰 릴리즈가 있다고 가정 해보십시오. 개발 상태는 "다음 릴리스"에 대한 준비가되었으며 버전 1.2 (1.1.6 또는 2.0이 아닌)이 될 것이라고 결정했습니다. 따라서 우리는 분기하고 새 버전 번호를 반영하는 이름을 릴리스 분기에 제공합니다.

$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)

새로운 브랜치를 생성하고 브랜치로 전환 한 후 버전 번호를 지정합니다. 여기서 bump-version.sh는 작업 복사본의 일부 파일을 새 버전을 반영하도록 변경하는 가상의 쉘 스크립트입니다. 물론 이것은 수동 변경 일 수 있습니다. 즉, 일부 파일이 변경된다는 점입니다. 그런 다음 범프된 버전 번호가 커밋됩니다.

 

이 새로운 분기는 해당 릴리스가 확실히 출시될 때까지 잠시 동안 존재할 수 있습니다. 그 시간 동안 버그 수정은 이 브랜치 (개발 브랜치보다는)에서 적용될 수 있습니다. 여기에 큰 새로운 기능을 추가하는 것은 엄격히 금지되어 있습니다. 그들은 병합되어 개발되어야 하므로 다음 큰 릴리스를 기다려야 합니다.

Finishing a release branch 

릴리스 분기의 상태가 실제 릴리스가 될 준비가 되면 일부 작업을 수행해야 합니다. 첫째, 릴리스 분기는 마스터에 병합됩니다 (마스터의 모든 커밋은 정의에 따라 새로운 릴리스이므로 기억하십시오). 다음으로, 마스터에 대한 커밋은 이 히스토리 버전에 대한 나중에 쉽게 참조 할 수 있도록 태그가 지정되어야 합니다. 마지막으로 릴리스 지점에서의 변경 사항을 병합하여 다시 개발해야하므로 향후 릴리스에도 이러한 버그 수정 사항이 포함될 수 있습니다.

 

Git의 처음 두 단계 :

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2

이제 릴리스가 완료되고 나중에 참조 할 수 있도록 태그가 추가됩니다.

 

편집 : 태그를 암호로 서명하려면 -s 또는 -u <key> 플래그를 사용하는 것이 좋습니다.

 

릴리즈 브랜치에서 변경된 사항을 유지하려면, 다시 변경해야합니다. Git에서 :

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)

이 단계는 병합 충돌을 일으킬 수 있습니다 (버전 번호를 변경했기 때문에). 그렇다면 수정하고 커밋하십시오.

 

이제 우리는 실제로 끝났고 릴리스 분기는 더 이상 필요하지 않으므로 제거 될 수 있습니다.

$ git branch -d release-1.2
Deleted branch release-1.2 (was ff452fe).

Hotfix branches 

다음으로부터 분기 할 수 있습니다 :
    master
다시 병합해야합니다.
    develop과 master
분기 명명 규칙 :
    hotfix-*

 

핫픽스 분기점은 릴리스 계획과 매우 흡사합니다. 이는 계획되지는 않았지만 새로운 프로덕션 릴리스를 준비하기 위한 것이기도 합니다. 그들은 라이브 프로덕션 버전의 원치 않는 상태에 즉각적으로 대처해야 할 필요성에서 비롯됩니다. 프로덕션 버전의 치명적인 버그를 즉시 해결해야 하는 경우 핫픽스 분기는 프로덕션 버전을 표시하는 마스터 분기의 해당 태그에서 분기 될 수 있습니다.

 

본질은 다른 팀원이 빠른 생산 수정을 준비하는 동안 팀 구성원 (개발 지점)의 작업을 계속할 수 있다는 것입니다.

203892234_1549989623.9689.png

Creating the hotfix branch 

마스터 분기에서 핫픽스 분기가 만들어집니다. 예를 들어 버전 1.2는 현재 라이브로 실행되고 심각한 버그로 인해 문제를 일으키는 프로덕션 릴리스라고 가정해 봅시다. 그러나 개발(develop)상의 변경은 아직 불안정합니다. 그러면 우리는 핫픽스 분기를 분리하여 문제를 해결하기 시작할 수 있습니다.

$ git checkout -b hotfix-1.2.1 master
Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
1 files changed, 1 insertions(+), 1 deletions(-)

분기 후에 버전 번호를 바꾸는 것을 잊지 마라!

 

그런 다음 버그를 수정하고 수정 사항을 하나 이상의 별도 커밋으로 커밋하십시오.

$ git commit -m "Fixed severe production problem"
[hotfix-1.2.1 abbe5d6] Fixed severe production problem
5 files changed, 32 insertions(+), 17 deletions(-)

Finishing a hotfix branch 

완료되면 버그 픽스가 마스터로 다시 병합되어야 하지만, 버그 픽스가 다음 릴리스에도 포함되도록 하기 위해 개발(develop)에 다시 통합될 필요가 있습니다. 이는 릴리스 분기가 완료되는 방법과 완전히 유사합니다.

 

먼저 마스터를 업데이트하고 릴리스에 태그를 지정합니다.

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2.1

편집 : 태그를 암호로 서명하려면 -s 또는 -u <key> 플래그를 사용하는 것이 좋습니다.

 

다음으로 bugfix를 개발에 포함 시키십시오.

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)

여기에 있는 규칙의 한 가지 예외는 배포 분기가 현재 존재할 때 핫픽스 변경 사항을 개발 대신 배포 분기에 병합해야 한다는 것입니다. 버그픽스를 릴리즈 브랜치로 역 병합하면 결국 릴리즈 브랜치가 끝나면 버그 픽스도 함께 병합됩니다. (개발중인 작업이 즉시 이 버그픽스를 필요로하고 릴리스 분기가 끝날 때까지 기다릴 수 없는 경우 이미 버그픽스를 개발(develop)에 병합할 수 있습니다.)

 

마지막으로 임시 분기를 제거하십시오.

$ git branch -d hotfix-1.2.1
Deleted branch hotfix-1.2.1 (was abbe5d6).

Summary 

이 브랜치 모델에 새로운 것은 전혀 놀라운 것이 없지만,이 포스트가 시작된 "큰 그림"은 우리 프로젝트에서 굉장히 유용하다는 것이 밝혀졌습니다. 이해하기 쉬운 우아한 정신 모델을 형성하고 팀 구성원이 분기 및 릴리스 프로세스에 대한 공유 된 이해를 개발할 수 있습니다.

그림의 고품질 PDF 버전이 여기에 제공됩니다. 계속해서 언제든지 빠른 참조를 위해 벽에 걸 수 있습니다.

 

업데이트 : 그리고 요청한 사람 : 기본 다이어그램 이미지 (Apple Keynote)의 gitflow-model.src.key가 있습니다.

 

영문링크에 PDF 파일과 애플 키노트 파일이 있습니다.

 

 

추천
0

댓글 1개

전체 41 |RSS
Git 내용 검색

회원로그인

진행중 포인트경매

  1. 참여3 회 시작24.04.19 15:40 종료24.04.26 15:40
(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT