Beste Verzweigungsstrategie bei kontinuierlicher Integration?


100

Was ist die beste Verzweigungsstrategie, wenn Sie eine kontinuierliche Integration durchführen möchten?

  1. Release-Verzweigung: Entwickeln Sie auf dem Trunk und behalten Sie für jede Version einen Zweig.
  2. Feature-Verzweigung: Entwickeln Sie jedes Feature in einem separaten Zweig und führen Sie es erst zusammen, wenn es stabil ist.

Ist es sinnvoll, beide Strategien zusammen anzuwenden? Wie in verzweigen Sie für jede Version, aber Sie verzweigen auch für große Funktionen? Passt eine dieser Strategien besser zur kontinuierlichen Integration? Wäre eine kontinuierliche Integration überhaupt sinnvoll, wenn ein instabiler Trunk verwendet wird?


2
Randnotiz: Einige würden argumentieren, dass selbst wenn neue Funktionen eingeführt werden, alles immer stabil sein sollte. Auf der anderen Seite könnte das etwas idealistisch sein.
Keith Pinson

Antworten:


21

Ich finde das Thema wirklich interessant, da ich mich bei meiner täglichen Arbeit stark auf Filialen verlasse.

  • Ich erinnere mich, dass Mark Shuttleworth ein Modell vorschlug, um den Hauptzweig makellos zu halten und dabei über das herkömmliche CI hinauszugehen. Ich stellte darüber hier .
  • Da ich mit Tempomat vertraut bin, habe ich hier auch über Aufgabenbereiche und CI gebloggt . Es ist eine Schritt-für-Schritt-Anleitung, die erklärt, wie es mit Plastic SCM geht .
  • Schließlich fand ich einige der Themen zu CI (und möglicherweise zu Verzweigungen) in Duvalls Buch über CI auch sehr interessant .

Ich hoffe, Sie finden die Links interessant.


Wir haben Bamboo um Unterstützung für Verzweigungen pro Aufgabe erweitert. Codicesoftware.blogspot.com/2012/02/… , und es scheint, dass die neueste Version dies nativ mit mehreren Versionskontrollen, einschließlich dvcs, tun wird.
Pablo

20

Die Antwort hängt von der Größe Ihres Teams und der Qualität Ihrer Quellcodeverwaltung sowie von der Fähigkeit ab, komplexe Änderungssätze korrekt zusammenzuführen. Beispielsweise kann die vollständige Quellcodeverwaltung wie CVS- oder SVN-Zusammenführung schwierig sein, und Sie sind möglicherweise mit dem ersten Modell besser dran. Wenn Sie ein komplexeres System wie IBM ClearCase verwenden und ein größeres Team haben, sind Sie mit dem zweiten Modell möglicherweise besser dran Modell oder eine Kombination aus beiden.

Ich persönlich würde das Feature-Branch-Modell, bei dem jedes Haupt-Feature in einem separaten Branch entwickelt wird, mit Task-Sub-Branches für jede Änderung, die von einem einzelnen Entwickler vorgenommen wird, trennen. Wenn sich die Features stabilisieren, werden sie mit dem Trunk zusammengeführt, wodurch Sie einigermaßen stabil bleiben und alle Regressionstests jederzeit bestehen. Wenn Sie sich dem Ende Ihres Release-Zyklus nähern und alle Feature-Zweige zusammengeführt werden, stabilisieren und verzweigen Sie einen Release-System-Zweig, auf dem Sie nur Stabilitätsfehlerbehebungen und erforderliche Backports durchführen, während der Trunk für die Entwicklung des nächsten Releases verwendet wird und Sie erneut Verzweigen Sie für neue Feature-Zweige. Und so weiter.

Auf diese Weise enthält Trunk immer den neuesten Code, aber Sie schaffen es, ihn einigermaßen stabil zu halten und stabile Beschriftungen (Tags) für wichtige Änderungen und Zusammenführungen von Features zu erstellen. Die Feature-Zweige entwickeln sich schnell und werden kontinuierlich integriert, und einzelne Task-Unterzweige können häufig sein Aktualisiert aus dem Feature-Zweig, damit alle an derselben Funktion synchron arbeiten und gleichzeitig andere Teams, die an anderen Features arbeiten, nicht betroffen sind.

Gleichzeitig haben Sie im Laufe der Geschichte eine Reihe von Release-Zweigen, in denen Sie Backports, Support und Bugfixes für Ihre Kunden bereitstellen können, die aus irgendeinem Grund auf früheren Versionen Ihres Produkts oder sogar nur auf der neuesten veröffentlichten Version bleiben. Wie beim Trunk richten Sie keine kontinuierliche Integration in die Release-Zweige ein. Sie werden sorgfältig integriert, nachdem alle Regressionstests und andere Release-Qualitätskontrollen bestanden wurden.

Wenn aus irgendeinem Grund zwei Features voneinander abhängig sind und Änderungen voneinander erfordern, können Sie in Betracht ziehen, entweder beide im selben Feature-Zweig zu entwickeln oder die Features regelmäßig stabile Teile des Codes in den Trunk zusammenzuführen und dann die Änderungen von zu aktualisieren Trunk, um Code zwischen Trunk-Zweigen auszutauschen. Wenn Sie diese beiden Features von anderen isolieren müssen, können Sie einen gemeinsamen Zweig erstellen, von dem aus Sie diese Feature-Zweige verzweigen und mit dem Sie Code zwischen den Features austauschen können.

Das obige Modell ist für Teams unter 50 Entwicklern und ein Quellcodeverwaltungssystem ohne spärliche Verzweigungen und ordnungsgemäße Zusammenführungsfunktionen wie CVS oder SVN nicht sehr sinnvoll, was dieses gesamte Modell zu einem Albtraum beim Einrichten, Verwalten und Integrieren machen würde.


5
Ich bin mir nicht sicher, ob ich damit einverstanden bin, dass das, was Sie beschreiben, für Teams unter 50 Entwicklern keinen Sinn ergibt. Ich sehe auch Vorteile für viel kleinere Teams. +1
Aardvark

2
Natürlich gibt es Vorteile für Teams jeder Größe. Die Frage ist, bei welcher Teamgröße die Vorteile die mit einem schweren Prozess verbundenen Kosten überwiegen.
Jiri Klouda

Dies ähnelt dem GitFlow- und / oder GitHubFlow-Modell. Ich glaube nicht, dass diese Modelle die kontinuierliche Integration (Continuous Integration, CI) erleichtern. Meiner Meinung nach ist Trunk Based Development eine signifikante Verbesserung dieser Modelle.
Yani

Sie können sehen, dass dieser Kommentar tatsächlich vor der ursprünglichen Version von git flow liegt. Ich bin mir nicht ganz sicher, was du mit "besser" meinst. Ich habe Teams von 1, 5, 25, 150, 1.000 und 20.000 Entwicklern unterstützt, die an Projekten arbeiten, die teilweise integriert wurden. Die Anforderungen variieren und "besser" ist ein sehr relativer Begriff. Müssen Sie jemals Code zurückportieren? Sicherheitsupdates? Wenn nicht, dann ist dein Leben einfach. SaaS ist eine direkte Folge von Einschränkungen, die durch die stammbasierte Entwicklung auferlegt werden. Feature-Flags sind genauso komplex wie Feature-Zweige. Außer Sie erfahren von Kunden nur, wenn eine Permutation von ihnen bricht.
Jiri Klouda

9

Ich persönlich finde es viel sauberer, einen stabilen Stamm zu haben und Verzweigungen zu haben. Auf diese Weise können Tester und dergleichen auf einer einzigen "Version" bleiben und vom Trunk aktualisieren, um alle Funktionen zu testen, die vollständig sind.

Wenn mehrere Entwickler an unterschiedlichen Funktionen arbeiten, können sie alle ihre eigenen separaten Zweige haben. Wenn sie fertig sind, können sie zum Trunk zusammengeführt werden und eine zu testende Funktion senden, ohne dass der Tester zu mehreren Zweigen wechseln muss, um verschiedene Funktionen zu testen.

Als zusätzlichen Bonus gibt es einige Integrationstests, die automatisch durchgeführt werden.


Verzweigen und markieren Sie immer noch für jede Hauptversion? Oder einfach taggen?
KingNestor

1
Es funktioniert gut mit CI, solange Feature-Zweige mit etwas Disziplin zu Trunk zusammengeführt werden, um keine fehlerhaften Builds zu haben. Ich verzweige und tagge für jede Produktionsversion, die nur zur Fehlerbehebung verwendet wird. Das kann sofort in den Stallkoffer verschmolzen werden.
Adnan

@king Ich würde sagen, das hängt wahrscheinlich davon ab, was Sie als Hauptversion bezeichnen, aber in beiden Fällen können Sie
taggen

5

Ich denke, jede Strategie kann mit kontinuierlicher Entwicklung verwendet werden, vorausgesetzt, Sie erinnern sich an eines der Schlüsselprinzipien, die jeder Entwickler jeden Tag für Trunk / Mainline festlegt.

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

BEARBEITEN

Ich habe dieses Buch über CI gelesen und die Autoren schlagen vor, dass die Verzweigung nach Veröffentlichung ihre bevorzugte Verzweigungsstrategie ist. Ich muss zustimmen. Die Verzweigung nach Funktionen macht für mich bei Verwendung von CI keinen Sinn.

Ich werde versuchen zu erklären, warum ich so denke. Angenommen, drei Entwickler nehmen jeweils einen Zweig, um an einem Feature zu arbeiten. Die Fertigstellung jeder Funktion dauert mehrere Tage oder Wochen. Um sicherzustellen, dass sich das Team kontinuierlich integriert, muss es sich mindestens einmal am Tag für die Hauptniederlassung engagieren. Sobald sie damit beginnen, verlieren sie den Vorteil, einen Feature-Zweig zu erstellen. Ihre Änderungen sind nicht mehr von allen Änderungen des anderen Entwicklers getrennt. Wenn dies der Fall ist, warum sollten Sie sich überhaupt die Mühe machen, Feature-Zweige zu erstellen?

Die Verwendung der Verzweigung nach Freigabe erfordert viel weniger Zusammenführung zwischen Verzweigungen (immer eine gute Sache), stellt sicher, dass alle Änderungen so schnell wie möglich integriert werden, und (bei korrekter Ausführung) stellt sicher, dass Ihre Codebasis immer zur Freigabe bereit ist. Der Nachteil bei der Verzweigung durch Freigabe ist, dass Sie bei Änderungen erheblich vorsichtiger sein müssen. Beispielsweise muss ein umfangreiches Refactoring schrittweise durchgeführt werden. Wenn Sie bereits ein neues Feature integriert haben, das Sie in der nächsten Version nicht möchten, muss es mithilfe eines Mechanismus zum Umschalten von Features ausgeblendet werden .

Noch eine Bearbeitung

Es gibt mehr als eine Meinung zu diesem Thema. Hier ist ein Blog-Beitrag, der Pro-Feature-Verzweigung mit CI ist

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


interessant, kann diesen Beitrag nicht mehr finden.
Jirong Hu

5

Release-Zweige sind sehr nützlich und sogar unbedingt erforderlich, wenn Sie mehrere Versionen Ihrer App warten müssen.

Feature-Zweige sind auch sehr praktisch, insbesondere wenn ein Entwickler an einer großen Änderung arbeiten muss, während andere noch neue Versionen veröffentlichen.

Für mich ist die Verwendung beider Mechanismen eine sehr gute Strategie.

Interessanter Link aus dem Buch SVN .


4

Ich habe dieses Modell vor kurzem gemocht, wenn ich Git benutze. Obwohl Ihre Frage mit "svn" gekennzeichnet ist, können Sie sie möglicherweise dennoch verwenden.

Kontinuierliche Integration kann bis zu einem gewissen Grad im Zweig "Entwickeln" (oder wie auch immer Sie es nennen) in diesem Modell erfolgen, obwohl lange laufende Feature-Zweige für zukünftige Versionen es nicht so starr machen würden, jede Änderung zu berücksichtigen, die irgendwo am Code vorgenommen wird. Die Frage bleibt, ob Sie das wirklich wollen. Martin Fowler tut es.


2

Kontinuierliche Integration sollte kein Faktor für die Bestimmung Ihrer Verzweigungsstrategie sein. Ihr Verzweigungsansatz sollte basierend auf Ihrem Team, dem in der Entwicklung befindlichen System und den verfügbaren Tools ausgewählt werden.

Trotzdem ...

  • Es gibt keinen Grund, warum CI nicht in beiden von Ihnen beschriebenen Ansätzen verwendet werden kann
  • Diese Ansätze funktionieren in Kombination recht gut
  • Keiner der beiden arbeitet "besser" als der andere
  • CI ist bei einem instabilen Kofferraum absolut sinnvoll

All dies wurde in der vierten Frage auf der Seite beantwortet, von der Sie die Diagramme übernommen haben: http://blogs.collab.net/subversion/2007/11/branching-strat/


2

Solange Sie die Prinzipien verstehen, können Sie die Best Practices immer wieder neu erfinden. Wenn Sie die Prinzipien nicht verstehen, werden Sie die Best Practices so weit bringen, bevor Sie aufgrund widersprüchlicher externer Anforderungen auseinanderfallen.

Die beste Einführung in das Mainline-Modell finden Sie unter: https://web.archive.org/web/20120304070315/http://oreilly.com/catalog/practicalperforce/chapter/ch07.pdf

Lesen Sie den Link. Wenn Sie die Grundlagen verstanden haben, lesen Sie den folgenden Artikel des ehrwürdigen Henrik Kniberg. Es wird Ihnen helfen, das Hauptmodell mit der kontinuierlichen Integration in Beziehung zu setzen.

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


O'Reilly Kapitel nicht mehr zugänglich
Jason S

1

Als wir unser Team gründeten, erbten wir eine Release-basierte Strategie von dem Anbieter, der ursprünglich das System entwickelt hatte, für das wir verantwortlich sein sollten. Es funktionierte bis zu dem Zeitpunkt, als unsere Kunden verlangten, dass mehrere entwickelte Funktionen nicht in einer Version enthalten sein sollten (fyi ~ 250k Codezeilen, ~ 2500 Dateien, Scrum mit XP SDLC).

Dann haben wir uns mit funktionsbasierten Zweigen befasst. Dies funktionierte auch eine Weile - etwa zwei Monate, bis wir feststellten, dass unser Regressionstestprozess mehr als zwei Wochen dauern würde, was zusammen mit der Unsicherheit darüber, was veröffentlicht werden würde, zu enormen Unannehmlichkeiten führte.

Der letzte "Nagel im Sarg" der reinen SC-Strategien kam, als wir beschlossen, dass wir 1. einen stabilen Stamm und 2. eine Produktion haben sollten, die ST-, UAT- und Regressions-getestete BINARIES enthalten sollte (nicht nur Quelle - denken Sie an CC.)

Dies führte uns dazu, eine Strategie zu entwickeln, die eine Mischung aus Feature- und Release-basierten SC-Strategien darstellt.

Wir haben also einen Kofferraum. Bei jedem Sprint verzweigen wir den Sprint-Zweig (für die nicht agilen Leute - ein Sprint ist nur ein zeitlich begrenzter Entwicklungsaufwand mit variabler Ausgabe basierend auf der Komplexität). Aus dem Sprint-Zweig erstellen wir die Feature-Zweige und die parallele Entwicklung beginnt in ihnen. Sobald die Funktionen vollständig sind und vom System getestet wurden und wir die Absicht haben, sie bereitzustellen, werden sie mit dem Sprint-Zweig zusammengeführt. Einige können über mehrere Sprints hinweg schweben, normalerweise die komplexeren. Sobald der Sprint fast zu Ende ist und die Funktionen vollständig sind, "benennen" wir den Sprint-Zweig in "Regression" um (dies ermöglicht CruiseControl, ihn ohne Neukonfiguration aufzunehmen), und dann beginnen die Regressions- / Integrationstests auf dem cc-build OHR. Wenn das alles erledigt ist, geht es in Produktion.

Kurz gesagt, funktionsbasierte Zweige werden verwendet, um Funktionen zu entwickeln, zu testen und zu testen. Der Sprint-Zweig (eigentlich der Release-Zweig) wird verwendet, um Features bei Bedarf und Integrationstest selektiv zusammenzuführen.

Hier ist eine Frage an die Community: Wir haben offensichtlich Probleme, eine kontinuierliche Integration durchzuführen, da die Entwicklung in vielen Niederlassungen stattfindet und der Aufwand für die Neukonfiguration von CruiseControl hoch ist. Kann jemand vorschlagen und beraten?


Ich stimme den Schlussfolgerungen nicht unbedingt zu, aber danke für die Diskussion Ihres Prozesses. Es gibt keine einheitliche Lösung.
RaoulRubin

0

So wie ich es sehe, möchten Sie eine begrenzte Anzahl von Zweigen haben, auf die Sie sich konzentrieren können. Da Sie Tests, Codequalitätsmetriken und viele interessante Dinge mit den Builds ausführen möchten, werden Sie bei zu vielen Berichten wahrscheinlich Informationen verpassen.

Wann und was verzweigt werden soll, hängt normalerweise von der Größe des Teams und der Größe der zu entwickelnden Funktionen ab. Ich glaube nicht, dass es eine goldene Regel gibt. Stellen Sie sicher, dass Sie eine Strategie verwenden, bei der Sie früh / häufig Feedback erhalten können. Dazu gehört auch, dass die Qualität von Anfang an berücksichtigt wird. Das Qualitätsbit bedeutet, dass Sie während der Automatisierung während der Teamentwicklung, wenn Sie nach einem großen Funktionsumfang verzweigen, den ein Team aufbaut, auch Qualität in das Team einbeziehen müssen.

ps Woher haben Sie diese Ansatzreferenzen? - glaubt nicht, dass diese Grafiken alle Optionen darstellen

Update 1: Erweitern, warum ich gesagt habe, dass es keine goldene Regel ist. Grundsätzlich habe ich es für relativ kleine Teams am besten mit einem Ansatz gefunden, der eine Mischung ist. Feature-Zweige werden erstellt, wenn es etwas lang ist und ein Teil des Teams weiterhin kleinere Features hinzufügt.


Es hat auch noch mehr. Ich bin jedoch der Meinung, dass Feature Branching und Release Branching die beiden häufigsten sind.
KingNestor

0

Dave Farley , Autor von Continuous Delivery , bezeichnete Trunk Based Development (TBD) als Eckpfeiler von Continuous Integration (CI) und Continuous Delivery (CD). Er sagt:

Jede Form der Verzweigung steht im Widerspruch zur kontinuierlichen Integration.

Er sagt auch:

Feature Branching ist aus Sicht eines einzelnen Entwicklers sehr schön, aus Sicht eines Teams jedoch nicht optimal. Wir alle möchten in der Lage sein, zu ignorieren, was alle anderen tun, und mit unserer Arbeit fortzufahren. Leider ist Code nicht so. Selbst in sehr gut faktorisierten Codebasen mit einer schönen Trennung von Bedenken und wunderbar lose gekoppelten Komponenten wirken sich einige Änderungen auf andere Teile des Systems aus.

Trunk Based Development (TBD) ist die Praxis, Codeänderungen mindestens einmal pro Tag - vorzugsweise mehrmals pro Tag - in den Trunk (auch bekannt als Master, Mainline) zu integrieren. Continuous Integration (CI) ist eine ähnliche Vorgehensweise, mit der Ausnahme, dass auch die Codeänderungen mithilfe automatisierter Tests überprüft werden. Die beste Verzweigungsstrategie hierfür besteht darin, direkt vom Trunk aus zu arbeiten und Codeüberprüfungen durch Pair-Programming durchzuführen . Wenn Sie aus irgendeinem Grund nicht koppeln können oder nur wirklich verzweigen möchten, stellen Sie sicher, dass Ihre Zweige nur von kurzer Dauer sind (weniger als einen Tag).

Ich arbeite an Trunk, "Master" in meinen GIT-Repos. Ich verpflichte mich, lokal zu mastern und pushe sofort, wenn ich vernetzt bin, zu meinem zentralen Master-Repo, in dem CI ausgeführt wird. Das ist es!

Versuchen Sie bei großen Funktionen (dh solchen, die länger als einen Tag dauern), sie in kleine Logikblöcke aufzuteilen, die in den Trunk integriert werden können, ohne die Software zu beschädigen. Sie können auch Techniken wie Feature-Flagging und Verzweigung nach Abstraktion verwenden, mit denen Sie unvollständige Arbeiten bereitstellen können, ohne die Endbenutzer zu beeinträchtigen.

Ich benutze Branch by Abstraction, Dark Release und manchmal Feature-Flags. Als Gegenleistung erhalte ich schnelles, endgültiges Feedback (zumindest zur Qualität meiner Tests).


Dave Farley und Jez Humble sind einfach falsch in ihrer Haltung zur Verzweigung. Der Grund dafür ist, dass es wichtige Annahmen codiert: "Sie müssen Code niemals auf Funktionsebene manipulieren, und wenn, dann ist es in Ordnung, dass es sich um einen teuren Betrieb handelt", und sie stützen ihre Einschätzung auf eine andere Annahme, dass das Zusammenführen mit automatisiert zu teuer ist Verschmelzungen sind im Maßstab nahezu unmöglich ". Wenn diese beiden Annahmen nicht zutreffen, wenn Sie in einer Welt leben, in der das Zusammenführen billig ist, aber Code auf Funktionsebene für Backports und Sicherheitskorrekturen manipulieren müssen, werden ihre Anweisungen nicht mehr angezeigt. Es ist ein seltener Fall.
Jiri Klouda

Einige Unternehmen müssen Funktionen auch auf zukünftige Versionen verschieben, nachdem diese Funktionen bei der Implementierung auf Straßensperren gestoßen sind und eine Version aufhalten. Manchmal gibt es eine Option, den Code zu belassen, wie bei SaaS-Produkten. Wenn der Code jedoch für Kunden freigegeben wird, ist er möglicherweise keine Option, da er von Wettbewerbern analysiert werden kann. Heutzutage wird so viel Code nicht kompiliert, und selbst wenn dies der Fall ist, haben Definitions- / Feature-Flags im Code dieselbe Komplexitätsstufe wie Zweige.
Jiri Klouda

-3

Ich denke, die Werkzeuge, die Sie verwenden, sind hier ein großer Faktor.

  • Wenn Sie Subversion verwenden, bleiben Sie bei Option 1 und lassen Sie sie von Zweigen los.
  • Wenn Sie GIT verwenden, funktioniert Option 2 gut für Sie.

2
Feature-Verzweigung kann leicht mit jedem SCM erreicht werden
hdost
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.