지속적인 통합을 수행 할 때 최고의 분기 전략?


100

지속적인 통합을 원할 때 가장 좋은 분기 전략은 무엇입니까?

  1. 릴리스 분기 : 트렁크에서 개발하고 각 릴리스에 대해 분기를 유지합니다.
  2. 기능 분기 : 각 기능을 별도의 분기에서 개발하고 안정된 경우에만 병합합니다.

이 두 가지 전략을 함께 사용하는 것이 합리적입니까? 에서와 같이 각 릴리스에 대해 분기하지만 큰 기능에 대해서도 분기합니까? 이러한 전략 중 하나가 지속적인 통합과 더 잘 맞을까요? 불안정한 트렁크를 사용할 때 지속적인 통합을 사용하는 것이 합리적일까요?


2
참고 : 일부는 새로운 기능이 추가 되더라도 모든 것이 항상 안정적이어야한다고 주장합니다. 반면에 그것은 다소 이상 주의적 일 수 있습니다.
Keith Pinson 2013 년

답변:


21

나는 일상 업무에서 지사에 크게 의존하기 때문에 주제가 정말 흥미로워 요.

  • Mark Shuttleworth가 기존 CI를 넘어서면서 메인 브랜치를 깨끗하게 유지하는 모델을 제안한 것을 기억합니다. 여기 에 그것에 대해 게시했습니다 .
  • Cruise Control에 익숙하기 때문에 여기에서 작업 분기 및 CI에 대한 블로그도 게시 했습니다 . Plastic SCM 으로 수행하는 방법을 설명하는 단계별 자습서 입니다.
  • 마지막으로, CI에 대한 Duvall의 책에서 CI에 대한 일부 주제 (그리고 잠재적으로 분기에 대해 이야기 할 수 있음) 도 매우 흥미로 웠습니다 .

흥미로운 링크를 찾으시기 바랍니다.


우리는 작업 별로 분기를 수행하도록 Bamboo에 지원을 추가 했습니다. codicesoftware.blogspot.com/2012/02/… , 최신 버전은 dvcs를 포함한 여러 버전 제어를 기본적으로 수행 할 것으로 보입니다.
pablo apr

20

대답은 팀의 규모와 소스 제어의 품질, 복잡한 변경 세트를 올바르게 병합하는 능력에 따라 다릅니다. 예를 들어 CVS 또는 SVN과 같은 전체 분기 소스 제어에서는 병합이 어려울 수 있으며 첫 번째 모델을 사용하는 것이 더 나을 수 있지만 IBM ClearCase와 같은 더 복잡한 시스템을 사용하고 팀 규모가 더 큰 경우 두 번째 모델이 더 나을 수 있습니다. 모델 또는 둘의 조합.

저는 개인적으로 각 주요 기능이 개별 개발자가 수행 한 각 변경 사항에 대한 작업 하위 분기와 함께 별도의 분기에서 개발되는 기능 분기 모델을 분리합니다. 기능이 안정화되면 트렁크에 병합되어 합리적으로 안정적으로 유지되고 항상 모든 회귀 테스트를 통과합니다. 릴리스주기가 거의 끝 나가고 모든 기능 분기가 병합되면 안정성 버그 수정 및 필요한 백 포트만 수행하는 릴리스 시스템 분기를 안정화하고 분기하는 반면 트렁크는 다음 릴리스의 개발과 다시 사용하는 데 사용됩니다. 새로운 기능 분기를 위해 분기합니다. 등등.

이러한 방식으로 트렁크에는 항상 최신 코드가 포함되지만,이를 합리적으로 안정적으로 유지하여 주요 변경 및 기능 병합에 대해 안정적인 레이블 (태그)을 생성 할 수 있습니다. 기능 분기는 지속적인 통합을 통해 빠르게 진행되는 개발이며 개별 작업 하위 분기가 자주 발생할 수 있습니다. 기능 브랜치에서 새로 고침을 통해 모든 사람이 동일한 기능에 대해 동기화 상태를 유지하면서 동시에 다른 기능을 작업하는 다른 팀에 영향을주지 않습니다.

동시에 역사를 통틀어 일련의 릴리스 브랜치가 있으며, 여기서는 어떤 이유로 든 제품의 이전 버전 또는 최신 릴리스 버전을 유지하는 고객에게 백 포트, 지원 및 버그 수정을 제공 할 수 있습니다. 트렁크와 마찬가지로 릴리스 분기에서 지속적인 통합을 설정하지 않고 모든 회귀 테스트 및 기타 릴리스 품질 관리를 통과 할 때 신중하게 통합됩니다.

어떤 이유로 두 기능이 상호 의존적이며 서로 변경해야하는 경우 동일한 기능 브랜치에서 둘 다 개발하거나 기능이 코드의 안정적인 부분을 트렁크에 정기적으로 병합 한 다음 변경 사항을 새로 고치는 것을 고려할 수 있습니다. 트렁크 분기간에 코드를 교환하기위한 트렁크. 또는 이러한 두 기능을 다른 기능과 분리해야하는 경우 해당 기능 분기를 분기하고 기능간에 코드를 교환하는 데 사용할 수있는 공통 분기를 만들 수 있습니다.

위의 모델은 50 명 미만의 개발자와 부족한 분기 및 CVS 또는 SVN과 같은 적절한 병합 기능이없는 소스 제어 시스템에서는별로 의미가 없습니다. 이로 인해 전체 모델을 설정, 관리 및 통합하는 데 악몽이 될 것입니다.


5
설명하신 내용이 개발자가 50 명 미만인 팀에게 적합하지 않다는 데 동의하는지 잘 모르겠습니다. 훨씬 작은 팀에게도 혜택을 볼 수 있습니다. +1
Aardvark

2
물론 규모에 관계없이 모든 팀에 이점이 있습니다. 문제는 무거운 프로세스와 관련된 비용보다 이점이 더 큰 팀 규모입니다.
Jiri Klouda

이는 GitFlow 및 / 또는 GitHubFlow 모델과 유사합니다. 이러한 모델이 CI (지속적 통합)를 용이하게한다고 생각하지 않습니다. 제 생각에 트렁크 기반 개발은 이러한 모델에서 상당한 개선입니다.
야니

이 주석이 실제로 git flow의 원래 릴리스보다 이전 버전임을 알 수 있습니다. "더 나은"이 무엇을 의미하는지 잘 모르겠습니다. 저는 어느 정도 통합 된 프로젝트를 작업하는 1, 5, 25, 150, 1,000 및 20,000 명의 개발자 팀을 지원했습니다. 요구 사항은 다양하며 "더 좋음"은 상대적인 용어입니다. 코드를 백 포트해야합니까? 보안 수정? 그렇지 않다면 당신의 삶은 간단합니다. SaaS는 트렁크 기반 개발에 의해 부과 된 제한의 직접적인 결과입니다. 기능 플래그는 기능 분기만큼 복잡합니다. 고객의 순열이 깨질 때만 고객에게서 알아내는 것을 제외하고는.
Jiri Klouda

9

저는 개인적으로 안정적인 트렁크를 갖고 기능 분기를 수행하는 것이 훨씬 더 깔끔하다는 것을 알았습니다. 이렇게하면 테스터 등이 단일 "버전"을 유지하고 트렁크에서 업데이트하여 코드가 완성 된 모든 기능을 테스트 할 수 있습니다.

또한 여러 개발자가 서로 다른 기능에 대해 작업하는 경우 모두 고유 한 분기를 갖고 완료되면 트렁크에 병합하고 테스터가 여러 가지 기능을 테스트하기 위해 여러 분기로 전환 할 필요없이 테스트 할 기능을 보낼 수 있습니다.

추가 보너스로 자동으로 제공되는 통합 테스트 수준이 있습니다.


또한 여전히 각 주요 릴리스에 대해 분기하고 태그를 지정합니까? 아니면 그냥 태그?
KingNestor

1
기능 브랜치가 일부 규율로 트렁크에 병합되어 빌드가 손상되지 않는 한 CI와 잘 작동합니다. 버그 수정에만 사용되는 각 프로덕션 릴리스에 대해 분기 및 태그를 수행합니다. 그것은 즉시 안정된 트렁크에 병합 될 수 있습니다.
Adnan

@king 아마도 당신이 메이저 릴리스라고 부르는 것에 달려 있다고 말하고 싶습니다. 그러나 어느 경우 든 태그를
달 수

5

각 개발자가 매일 트렁크 / 메인 라인에 투입하는 핵심 원칙 중 하나를 기억한다면 두 전략 모두 지속적인 개발과 함께 사용할 수 있다고 생각합니다.

http://martinfowler.com/articles/continuousIntegration.html#EveryoneCommitsToTheMainlineEveryDay

편집하다

나는 CI에 대한 이 책 을 읽고 있었고 저자들은 릴리스별로 분기하는 것이 선호하는 분기 전략이라고 제안합니다. 동의해야합니다. CI를 사용할 때 기능별로 분기하는 것은 의미가 없습니다.

내가 왜 이런 식으로 생각하는지 설명하려고 노력할 것입니다. 세 명의 개발자가 각각 한 가지 기능을 사용하여 작업한다고 가정합니다. 각 기능은 완료하는 데 며칠 또는 몇 주가 걸립니다. 팀이 지속적으로 통합되도록하려면 최소한 하루에 한 번 메인 브랜치에 전념해야합니다. 이 작업을 시작하자마자 기능 브랜치를 만드는 이점을 잃게됩니다. 그들의 변경 사항은 더 이상 다른 모든 개발자의 변경 사항과 분리되지 않습니다. 그렇기 때문에 애초에 기능 브랜치를 생성해야하는 이유는 무엇입니까?

릴리스 별 분기를 사용하면 분기 간의 병합이 훨씬 적고 (항상 좋은 일입니다) 모든 변경 사항이 최대한 빨리 통합되고 (올바르게 수행 된 경우) 항상 릴리스 준비가 된 코드 기반을 보장합니다. 릴리스 별 분기의 단점은 변경 사항에 대해 훨씬 더주의해야한다는 것입니다. 예를 들어 대규모 리팩토링은 점진적으로 수행되어야하며 다음 릴리스에서 원하지 않는 새 기능을 이미 통합 한 경우에는 일종의 기능 전환 메커니즘을 사용하여 숨겨야합니다 .

다른 편집

이 주제에 대해 하나 이상의 의견이 있습니다. 다음은 CI로 분기되는 프로 기능인 블로그 게시물입니다.

http://jamesmckay.net/2011/07/why-does-martin-fowler-not-understand-feature-branches/


흥미 롭습니다. 더 이상이 게시물을 찾을 수 없습니다.
Jirong Hu

5

릴리스 브랜치는 매우 유용하며 앱의 여러 버전을 유지해야하는 경우 절대적으로 필요합니다.

기능 브랜치는 매우 편리합니다. 특히 한 개발자가 큰 변경 작업을해야하고 다른 개발자는 여전히 새 버전을 출시해야하는 경우에 그렇습니다.

그래서 두 가지 메커니즘을 모두 사용하는 것은 매우 좋은 전략입니다.

Book of SVN 에서 흥미로운 링크 .


4

저는 최근에 git 을 사용할 때이 모델 을 좋아하게되었습니다 . 질문에 "svn"태그가 지정되어 있어도 여전히 사용할 수 있습니다.

지속적 통합은이 모델의 "develop"브랜치 (또는 당신이 부르는 무엇이든)에서 어느 정도 일어날 수 있지만, 향후 릴리스를 위해 기능 브랜치를 오래 실행한다고해서 어딘가에서 코드에 발생하는 모든 변경을 고려할만큼 엄격하지 않을 것입니다. 당신이 정말로 그것을 원하는지에 대한 질문은 남아 있습니다. Martin Fowler는 그렇습니다.


2

지속적인 통합은 분기 전략을 결정하는 요소가되어서는 안됩니다. 분기 접근 방식은 팀, 개발중인 시스템 및 사용 가능한 도구를 기반으로 선택해야합니다.

라고 한 ...

  • 설명하는 두 가지 접근 방식 모두에서 CI를 사용할 수없는 이유가 없습니다.
  • 이러한 접근 방식은 조합하여 매우 잘 작동합니다.
  • 두 가지 모두 다른 것보다 "더 잘"작동하지 않습니다.
  • CI는 불안정한 트렁크로 총체적으로 이해됩니다.

이 모든 내용은 다음 페이지에서 다이어그램을 가져온 페이지의 네 번째 질문에서 답변되었습니다. http://blogs.collab.net/subversion/2007/11/branching-strat/


2

원칙을 이해하는 한 항상 모범 사례를 다시 만들 수 있습니다. 원칙을 이해하지 못하는 경우 모범 사례는 충돌하는 외부 요구 사항으로 인해 해체되기 전에 훨씬 더 오래 걸릴 것입니다.

메인 라인 모델에 대한 최상의 소개는 다음을 참조 하십시오 : https://web.archive.org/web/20120304070315/http://oreilly.com/catalog/practicalperforce/chapter/ch07.pdf

링크를 읽으십시오. 기본 사항을 익힌 후에는 유명한 Henrik Kniberg의 다음 기사를 읽어보십시오. 메인 라인 모델과 지속적인 통합을 연결하는 데 도움이됩니다.

http://www.infoq.com/articles/agile-version-control


O'Reilly 장에 더 이상 액세스 할 수 없음
Jason S

1

우리 팀을 시작했을 때 우리는 우리가 맡게 될 시스템을 원래 개발 한 공급 업체로부터 릴리스 기반 전략을 물려 받았습니다. 고객이 몇 가지 개발 된 기능이 릴리스에 포함되지 않도록 요청했을 때까지 작동했습니다 (~ 250,000 라인의 코드, ~ 2500 개 파일, XP SDLC가있는 스크럼).

그런 다음 기능 기반 분기를 살펴보기 시작했습니다. 이것은 또한 잠시 동안 작동했습니다. 회귀 테스트 프로세스가 2 주 이상 걸릴 것이라는 것을 깨달을 때까지 2 개월 정도가 걸렸고 릴리스 될 내용의 불확실성과 함께 큰 불편을 초래했습니다.

순수한 SC 전략의 마지막 "관 속의 못"은 우리가 1. 안정된 트렁크와 2. 생산에 ST, UAT 및 회귀 테스트 된 BINARIES를 포함해야한다고 결정했을 때 나왔습니다 (소스뿐만 아니라 CC를 생각하십시오).

이를 통해 기능과 릴리스 기반 SC 전략을 혼합 한 전략을 고안 할 수 있습니다.

그래서 우리는 트렁크가 있습니다. 모든 스프린트는 스프린트 브랜치로 분기합니다 (민첩하지 않은 사용자의 경우 스프린트는 복잡성에 따라 가변 출력을 사용하는 타임 박스 개발 노력 일뿐입니다.) 스프린트 브랜치에서 기능 브랜치를 만들고 병렬 개발이 시작됩니다. 기능이 완료되고 시스템 테스트가 완료되고 배포 할 의도가 있으면 스프린트 브랜치에 병합됩니다. 일부는 여러 스프린트 (일반적으로 더 복잡한 스프린트)에 떠있을 수 있습니다. 스프린트가 거의 끝나고 기능이 완료되면 스프린트 브랜치의 이름을 "회귀"로 "이름을 변경"한 다음 (CruiseControl이 재구성없이이를 선택할 수있게 함) cc 빌드에서 회귀 / 통합 테스트가 시작됩니다. 귀. 이 작업이 모두 완료되면 프로덕션에 들어갑니다.

간단히 말해, 기능 기반 분기는 개발, 시스템 테스트 및 UAT 기능에 사용됩니다. 스프린트 브랜치 (실제로 릴리스 브랜치)는 온 디맨드 및 통합 테스트 기능을 선택적으로 병합하는 데 사용됩니다.

이제 커뮤니티에 대한 질문이 있습니다. 개발이 많은 지점에서 발생하고 CruiseControl의 재구성 오버 헤드로 인해 지속적인 통합을 수행하는 데 분명히 문제가 있습니다. 누군가 제안하고 조언 할 수 있습니까?


결론에 반드시 동의하지는 않지만 프로세스에 대해 논의 해 주셔서 감사합니다. 일률적 인 솔루션은 없습니다.
RaoulRubin 2014

0

내가보기에 당신은 당신이 집중할 수있는 제한된 지점들을 갖고 싶어한다. 테스트, 코드 품질 메트릭 및 빌드와 함께 실행되는 많은 흥미로운 것을 원하기 때문에 보고서가 너무 많으면 정보를 놓칠 수 있습니다.

분기시기와 대상은 일반적으로 팀의 규모와 개발중인 기능의 규모에 따라 다릅니다. 황금률은 없다고 생각합니다. 초기 / 자주 피드백을받을 수있는 전략을 사용하고, 여기에는 기능의 시작부터 품질을 포함하는 것이 포함됩니다. 품질 비트는 팀이 개발함에 따라 자동화 할 때 팀이 구축하고있는 대규모 기능 세트를 위해 분기하는 경우 팀에도 품질이 관여해야 함을 의미합니다.

추신 그 접근 참조는 어디서 얻었습니까? -그 그래프가 모든 옵션을 대표한다고 생각하지 않습니다.

업데이트 1 : 내가 황금률이 ​​아니라고 말한 이유를 확장합니다. 기본적으로 비교적 소규모 팀의 경우 혼합 방식을 사용하는 것이 가장 좋습니다. 기능 브랜치가 길면 생성되고 팀의 일부는 계속해서 더 작은 기능을 추가합니다.


더 많이 있습니다. 하지만 기능 분기와 릴리스 분기가 가장 일반적인 두 가지라고 생각합니다.
KingNestor

0

Continuous Delivery 의 저자 인 Dave FarleyTBD (Trunk Based Development) 를 CI (Continuous Integration) 및 CD (Continuous Delivery)의 초석으로 언급했습니다 . 그는 말한다 :

모든 형태의 분기는 지속적 통합에 반대됩니다.

그는 또한 말합니다,

기능 분기는 개별 개발자의 관점에서는 매우 좋지만 팀 관점에서는 차선책입니다. 우리 모두는 다른 사람들이하는 일을 무시하고 일을 계속할 수 있기를 바랍니다. 불행히도 코드는 그렇지 않습니다. 아름다운 문제 분리와 놀랍도록 느슨하게 결합 된 구성 요소가있는 매우 잘 구성된 코드베이스에서도 일부 변경 사항은 시스템의 다른 부분에 영향을줍니다.

트렁크 기반 개발 (TBD) 은 코드 변경 사항을 적어도 하루에 한 번 (가급적이면 하루에 여러 번) 트렁크 (즉, 마스터, 메인 라인)에 통합하는 관행입니다. CI (지속적 통합)는 자동화 된 테스트를 사용하여 코드 변경 사항을 확인한다는 점을 제외하면 유사한 방식입니다. 이를위한 가장 좋은 분기 전략은 트렁크에서 직접 작업하고 Pair-Programming을 통해 코드 검토를 수행하는 것 입니다. 어떤 이유로 든 페어링 할 수 없거나 정말로 분기하고 싶은 경우 분기의 ​​수명이 짧아야합니다 (하루 미만).

저는 GIT 저장소의 "마스터"인 Trunk에서 작업합니다. 로컬에서 마스터하고 네트워크에 연결되면 CI가 실행되는 중앙 마스터 리포지토리로 즉시 푸시합니다. 그게 다야!

큰 기능 (예 : 하루 이상 걸리는 기능)의 경우 소프트웨어를 손상시키지 않고 트렁크에 통합 할 수있는 작은 논리 덩어리로 분리하십시오. 또한 최종 사용자에게 영향을주지 않고 불완전한 작업을 배포 할 수있는 추상화에 의한 기능 플래그 지정분기 와 같은 기술을 사용할 수 있습니다 .

추상화, 다크 릴리스 및 때로는 기능 플래그로 분기를 사용합니다. 내가받는 대가는 빠르고 확실하다 (적어도 내 테스트 품질에 비하면) 피드백입니다.


Dave Farley와 Jez Humble은 분기에 대한 입장이 잘못되었습니다. 그 이유는 "기능 수준에서 코드를 조작 할 필요가 없으며 비용이 많이 드는 작업이면 괜찮은 경우"라는 중요한 가정을 인코딩하고 "자동화를 사용하면 병합이 너무 비싸다"라는 다른 가정을 기반으로 평가하기 때문입니다. 합병은 거의 불가능합니다. " 이 두 가지 가정이 사실이 아니라면 병합 비용이 저렴하지만 백 포트 및 보안 수정을 위해 기능 수준에서 코드를 조작해야하는 경우 해당 명령문이 무너집니다. 드문 경우입니다.
Jiri Klouda

일부 회사는 이러한 기능이 구현에 장애가되고 릴리스를 보류 한 후 향후 릴리스로 기능을 이전해야합니다. 때로는 SaaS 제품과 같이 코드를 그대로 두는 옵션이 있지만 코드가 고객에게 공개되면 경쟁사에서 분석 할 수 있으므로 옵션이 아닐 수 있습니다. 요즘에는 너무 많은 코드가 컴파일되지 않으며, 그렇더라도 코드의 정의 / 기능 플래그는 분기와 동일한 복잡성 수준에 있습니다.
Jiri Klouda

-3

여기에서 사용하는 도구가 큰 요인이라고 생각합니다.

  • Subversion을 사용하는 경우 옵션 1을 고수하고 분기에서 해제하십시오.
  • GIT를 사용하는 경우 옵션 2가 적합합니다.

2
기능 분기는 모든 SCM으로 쉽게 달성 할 수 있습니다.
hdost 2015
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.