Wie gehen Sie mit der Integration von Code aus mehreren Zweigen / Entwicklern pro Sprint um?

42

Ich habe gerade einen Retro-Anruf erhalten, bei dem die Entwickler ihre Besorgnis über die Integration ihrer Storys in die Master-Branche zum Ausdruck brachten. Die Entwickler codieren alle in ihrem eigenen Zweig und verschmelzen gegen Ende des Sprints zu einem Hauptzweig.

Dann muss ein Entwickler (normalerweise derselbe) sicherstellen, dass sich alles gut in den Code anderer Entwickler integriert hat (Die meisten Änderungen befinden sich auf derselben Seite. Beispiel: Datenanzeigestory, Datenfilterstory und ein SLA-Indikator).

Wie können wir diese Belastung verringern und das Zusammenführen unseres Codes erleichtern? Aus meiner Sicht können einige Probleme gelöst werden, wenn die PO oder SM die Storys auf effizientere Weise priorisieren, damit wir diese Art von Abhängigkeiten nicht im selben Sprint haben. Wie gehen alle anderen damit um? Oder ist das nur ein Teil des Prozesses?

Ausstechform
quelle
18
Haben Sie keine Entwicklungsabteilung, in der die kontinuierliche Integration erfolgt?
Kayaman
13
Ich bin mit Kayaman hier, die beste Praxis hierfür ist die Implementierung einer kontinuierlichen Integration.
RandomUs1r
27
Happy Merge Day! Jedes Mal, wenn Ihr Problem etwas in The Daily WTF zu ähnlich ist, wissen Sie, dass Sie in Schwierigkeiten sind.
user3067860
Früh zusammenführen, oft zusammenführen: {Schreiben Sie den kleinsten Testcode, der fehlschlägt (rot), schreiben Sie den kleinsten Produktionscode, der erfolgreich ist (grün), refaktorieren Sie, wiederholen Sie den Test, führen Sie den Test zusammen}, solange er noch nicht abgeschlossen ist.
Strg-Alt-Delor
1
Erster Check-in gewinnt! Sei niemals der Letzte! :-)
ChuckCottrill

Antworten:

88

Wenn Sie Git verwenden, zieht jeder Entwickler aus dem developZweig in seinen eigenen Feature-Zweig , um sicherzustellen, dass er nicht zu weit von der aktuellen Grundlinie entfernt ist. Sie können dies täglich tun, sodass Aufgaben, die länger als ein paar Tage dauern, synchron bleiben und Probleme beim Zusammenführen behoben werden, solange sie noch klein sind.

Wenn der Entwickler mit seiner Arbeit fertig ist, erstellt er eine Pull-Anfrage . Wenn genehmigt, wird das in der developFiliale zusammengeführt.

Die developFiliale sollte immer über Arbeitscode verfügen und jederzeit zur Veröffentlichung bereit sein. Wenn Sie tatsächlich Release machen, verschmelzen Sie developin masterund Tag setzen.

Wenn Sie über einen guten Continuous Integration Server verfügen, wird jeder Zweig beim Einchecken von Änderungen erstellt, insbesondere für Pull-Anforderungen. Einige Build-Server werden in Ihren Git-Server integriert, um eine Pull-Anforderung automatisch zu genehmigen oder abzulehnen, wenn der Build fehlschlägt oder die automatisierten Tests fehlschlagen. Dies ist ein weiterer Weg, um mögliche Integrationsfehler zu finden.

Berin Loritsch
quelle
73
Der wichtige Teil (der nur in Ihrer Antwort enthalten ist) ist, dass die Zweige zusammengeführt werden sollten, sobald sie fertig sind, in der Regel mit nur 1 - 5 Commits und nicht nur am Ende des Sprints. Ein Zweig pro Feature / Story, kein Zweig pro Entwickler. Das setzt voraus, dass Geschichten wirklich winzig sind, dh höchstens zwei Tage dauern.
Amon
@amon, stimmte zu. Die Wörter "Feature Branch" wurden hinzugefügt, aber versucht, diese Antwort ziemlich klein zu halten. Es gibt viele gute Artikel, die diesen Prozess vertiefen.
Berin Loritsch
5
Bleiben Sie nicht auf Ihrem eigenen Zweig isoliert. So beginnt die Hölle der Verschmelzung. Verwenden Sie die Hauptentwicklungsfunktion, isolieren Sie laufende Arbeiten hinter Funktionsumschaltungen oder andere Laufzeitkonfigurationen.
Rob Crawford
3
@Zibbobz Mein Team verwendet explizite "Feature Branches" für diejenigen, die grundsätzlich wie der Entwicklungszweig behandelt werden, jedoch nur für Pull-Anforderungen und Commits, die sich auf diese Änderung beziehen. Je nachdem, wie lange es getrennt bleiben muss, werden die Änderungen im Allgemeinen alle paar Tage von jemandem aus der Entwicklung in die Funktion integriert und Probleme behoben. Auf diese Weise sind sich die Zweige beim Zusammenführen so ähnlich wie möglich. Als Hinweis, dies ist nur für wirklich große Änderungen
reffu
9
"Work-in-Progress hinter Feature-Umschaltern oder anderen Laufzeitkonfigurationen isolieren" Sie haben die Hölle nur vermieden, indem Sie stattdessen in die Konfigurationshölle gegangen sind. "Merge Hell" ist immer nur ein Problem für einen Entwickler und kann einfach durch regelmäßige Synchronisierung vermieden werden. Tonnenweise kurzlebige Konfigurationen sind für alle zukünftigen Entwickler die Hölle.
Cubic
23

Ich habe in einem Team gearbeitet, in dem wir mit dem gleichen Problem zu kämpfen hatten. Wir stellten fest, dass es umso weniger schwierig wurde, je weniger Zeit wir vor der Integration hatten. Ich weiß, dass die meisten Leute, die die kontinuierliche Integration unterrichten, davon sprechen, alle paar Minuten etwas zu tun - wahrscheinlich haben wir tatsächlich jede Stunde etwas zu tun.

Wir fanden auch, dass nur Bauen nicht genug war. Wir brauchten eine gute Testabdeckung, um sicherzugehen, dass wir nicht versehentlich den Code des jeweils anderen brechen.

Daniel
quelle
2
Das ist auch meine Erfahrung. Es spielt eigentlich keine Rolle, wie oft Sie einen Commit durchführen, aber sobald Sie einen Commit durchgeführt haben, spart die Integration / Zusammenführung des Commits eine Menge Aufwand auf der ganzen Linie. Ich war einmal in einem Projekt, in dem wir drei unterschiedliche Entwicklungszweige hatten, die jeweils monatelang arbeitsintensiv waren. Sie zu verschmelzen machte keinen Spaß. Ich habe viel aus diesem Fehler gelernt :)
amon
4
Ja - das bedeutet "kontinuierliche Integration"! Sie integrieren Ihre Änderungen kontinuierlich in die Änderungen der anderen Entwickler!
Rob Crawford
@ Rob, einverstanden. Meine Aussage sollte nicht bedeuten, dass kontinuierliche Integration nicht kontinuierlich ist. Nur, dass wir nicht ganz das Ideal gemacht haben und trotzdem viele Vorteile darin gesehen haben, uns dem zu nähern.
Daniel
12
  • Halten Sie Ihre Zweige von kurzer Dauer (es hört sich so an, als ob Sie dies bereits tun).
  • Lassen Sie Ihre Testergebnisse für sich sprechen.
  • Warten Sie nicht bis zum Ende des Sprints.

Sie müssen TDD nicht einmal abonnieren. Sie benötigen lediglich einige Tests, die belegen, dass die Funktionen Ihrer Entwickler ordnungsgemäß funktionieren. Dies können Unit-Tests und Integrationstests sein, im Idealfall jedoch mehrere automatisierte End-to-End-Tests der kritischen Funktionen. Standard-Regressionspaket.

Sobald Ihre Zusammenführung abgeschlossen ist, können Sie den Automatisierungstestbericht zusammen überprüfen und sicherstellen, dass alles erfolgreich integriert wurde.

Ich stimme einer der anderen Antworten zu, in denen der Autor angegeben hat, dass Git PRs dieses Problem lösen würden, indem jeder Entwickler seine eigene Arbeit zusammenführen würde.

Ein weiterer Punkt, der meiner Meinung nach wichtig genug ist, um bis zum letzten Absatz zu bleiben. Ich schlage vor, dass Sie Ihre nächtlichen Builds manuell testen, anstatt bis zum Ende des Sprints zu warten. Entwickler sollten sich zusammenschließen, sobald das Feature vollständig ist, damit es so schnell wie möglich integriert, bereitgestellt und getestet werden kann.

Liath
quelle
6

Nicht

Abhängig von Ihrer Sprache und den Dateien, die Sie bearbeiten, ist es möglicherweise nicht sinnvoll, dass jeder Entwickler sie in seinem eigenen Zweig bearbeitet. In C # habe ich beispielsweise festgestellt, dass es am besten ist, wenn jeweils nur eine Person Benutzeroberflächendesignerdateien bearbeitet. Da es sich um automatisch generierte Dateien handelt, wird der Code manchmal ohne ersichtlichen Grund verschoben - und dies führt bei den meisten Zusammenführungswerkzeugen zu Problemen.

Dies bedeutet, dass einige Storys andere Storys blockieren können, bis die Arbeit an der Benutzeroberfläche abgeschlossen ist. Und / oder es wird eine neue Story erstellt, um nur die Benutzeroberfläche zu gestalten, wobei die anderen Storys Funktionen implementieren. Oder vielleicht erledigt ein Entwickler die gesamte Benutzeroberfläche, während andere die Funktionalität dieser Benutzeroberfläche implementieren.

Wenn Sie wissen, dass mehrere Storys dieselbe (n) Datei (en) berühren, möchten Sie möglicherweise vermeiden, alle gleichzeitig zu bearbeiten. Ziehe sie nicht alle in den gleichen Sprint oder arbeite erst an ihnen, wenn einer oder mehrere erledigt sind.

mmathis
quelle
Um ehrlich zu sein, ist das verwendete Tool zur Versionskontrolle für eine erfolgreiche Verzweigung und Zusammenführung von entscheidender Bedeutung. Selbst mit C # -Code und dem vermutlich WinForms- oder WebForms-Code, mit dem Sie arbeiten müssen, ändert sich in der Regel nicht viel . Wenn dies der Fall ist, müssen Sie möglicherweise einige Modelle erstellen, bevor Sie mit Code spielen können. XAML-basierte Benutzeroberflächen sind genauso stabil wie regulärer Code und Zwischencode wird nicht eingecheckt.
Berin Loritsch
2
@BerinLoritsch Der WinForms-Designercode kann sich in der Tat sehr ändern, selbst bei kleinen visuellen Änderungen. Ich habe festgestellt, dass die Codezeilen selbst identisch sind, die Reihenfolge jedoch sehr unterschiedlich ist - insbesondere, wenn mehrere Entwickler gleichzeitig Änderungen vornehmen. Vielleicht handelt es sich um ein Problem mit dem VCS-Tool (wir haben mehrere verwendet, vielleicht verwenden wir nur die falschen), aber für uns ist es viel einfacher, unseren Prozess geringfügig zu ändern.
MMATHIS
2
@BerinLoritsch Ich muss mmathis hier zumindest für Winformulare (nie benutzte Webformulare) an zweiter Stelle setzen. Der Benutzeroberflächendesigner von winforms liebt es, den gesamten Code in der Designer-Datei nach dem Zufallsprinzip neu anzuordnen, wenn sich irgendwo im Formular eine geringfügige Änderung ergibt. Wenn Sie die Neuanordnungen nicht vor jedem Festschreiben manuell rückgängig machen (was bei einem komplexen Formular leicht 10 oder 15 Minuten dauern kann), ist der Verlauf der Designer-Datei absolut nutzlos. Wenn 2 Personen gleichzeitig an der Benutzeroberfläche des Formulars arbeiten, führt dies zu ein Verschmelzungskonflikt aus der Hölle. Das Sperren ist im Allgemeinen eine schreckliche Option, aber mit WinForms ist das wirklich am wenigsten schlimm.
Dan Neely
@DanNeely, das ist nur einer der Gründe, warum unser Team von WinForms-Code abgewichen ist. Ein weiterer Grund ist, dass der Designer furchtbar zerbrechlich ist und einige unserer komplexen Formulare sowieso nicht visuell bearbeitet werden konnten. Wir mussten letztendlich Änderungen direkt im Codebehind vornehmen - wahrscheinlich, warum ich mich dort nicht an zu viele Umwälzungen erinnere. Das und unsere Benutzer, die mit hochdichten Displays arbeiten, haben uns wirklich zu WPF gebracht. Ein schmerzhafter Prozess mit einer hohen Lernkurve, aber einer schönen Belohnung am Ende. Die meisten Stories im Backlog waren sowieso für verschiedene Teile der App.
Berin Loritsch
@BerinLoritsch gleich hier. Win Forms bezahlte einen Großteil meiner Rechnungen für den größten Teil eines Jahrzehnts in meinem vorherigen Job, aber ich bin sehr froh, dass ich sie in Zukunft nie wieder anfassen werde.
Dan Neely
2

Ein weiterer möglicher Ansatz, um verspätete und große Zusammenführungen zu vermeiden, sind Feature-Flags : Sie schützen Ihre Änderungen mit einem (idealerweise dynamisch) konfigurierbaren Flag, das verhindert, dass sie vor dem beabsichtigten Einsatz aktiv werden.

Auf diese Weise können Sie Ihre Änderungen frühzeitig entweder in masterIhren gemeinsamen Entwicklungszweig zurückführen, ohne etwas zu beschädigen. Andere Entwickler können diese Änderungen dann wieder in ihre Feature-Zweige einfügen (oder ihre Zweige entsprechend umbasieren).

Wie die anderen Antworten bereits gezeigt haben, sollte dies mit einer kontinuierlichen Integrationslösung kombiniert werden.

Feature-Flags bieten zusätzliche Vorteile (zum Beispiel vereinfachen sie die Durchführung von A / B-Tests). Weitere Informationen finden Sie in diesem Artikel von Martin Fowler .

Florian Brucker
quelle
0

Wir verfolgen einen Ansatz mit einem separaten Entwicklungszweig für jedes Feature und führen dann die Zweige zu einem QS-Zweig zusammen, um sie in einer Integrationstestumgebung zu testen.

Sobald der Regressionstest und der Integrationstest abgeschlossen sind, können die einsatzbereiten Funktionen problemlos in den Release-Zweig verschoben werden.

Wenn alles in Ordnung ist, führen wir den Release-Zweig wieder zum Master-Zweig zusammen.

Emarshah
quelle
0

Vereinfacht ausgedrückt, verringern das Festschreiben und Zusammenführen häufig das Zeitfenster für Zusammenführungskonflikte und verringern Konflikte erheblich. Der andere Teil ist in der Tat die Planung durch den Lead, was einen reibungslosen Arbeitsfluss sicherstellen kann.

Die anderen Antworten bieten einen guten Einblick in die Best Practices für Commits. Wenn Sie diese einfach befolgen, reduzieren Sie wahrscheinlich den größten Teil Ihrer Zusammenführungsprobleme. Weitere Zusammenschlüsse sind mit ziemlicher Sicherheit erforderlich, aber für ein kleineres Team funktioniert der Ansatz "Filiale pro Person" wahrscheinlich gut genug. Natürlich tut es nicht (viel) weh, sich auf erweiterbare Praktiken einzulassen!

Es scheint jedoch, als hätte sich niemand mit einer Ihrer wichtigsten Fragen befasst - was tun, wenn Sie alle dieselben Codebereiche berühren? Hier ist es nützlich, einen Lead zu haben, der mit der Codebasis vertraut ist und Abhängigkeiten verschiedener Aufgaben erkennt. Wenn sie das Timing der Arbeit und der Festschreibungen nicht koordinieren, kommt es wahrscheinlich zu Zusammenführungskonflikten und zu einer zeilenweisen Auflösung. Das Organisieren der Aufgaben ist bei einem größeren Team viel schwieriger, aber bei einem kleinen Team ist es möglich, diese widersprüchlichen Aufgaben zu identifizieren. Der Leiter könnte dann sogar alle zugehörigen Aufgaben auf denselben Ingenieur verlagern, um den Konflikt insgesamt zu vermeiden.

Mars
quelle