Der allgemeine Workflow für Git (Git Flow) verwendet Feature-Branches, wobei für jedes neue Feature ein separater Branch erstellt wird. Entwickler implementieren neue Funktionen in diesen isolierten Zweigen und führen ihre Änderungen dann wieder in den main
oder master
Zweig ein.
Die Vorteile dieses Workflows liegen auf der Hand: Ein separater Zweig kann bequem in der QA-Umgebung bereitgestellt und getestet werden, und wenn kritische Fehler erkannt werden, wird er einfach nicht mit dem main
zusammengeführt. Im selben Zweig können Probleme behoben und der Code verbessert werden.
Unterdessen bleibt der Hauptzweig ständig einsatzbereit und vor diesen Problemen geschützt.
Leider hat diese Strategie einen erheblichen Nachteil: Zusammenführungskonflikte. Bei langlebigen Zweigen, die irgendwann unvermeidlich sind, können diese Konflikte zu schwer zu lösen sein, als dass es einfacher wäre, den Zweig ganz loszuwerden und von vorne zu beginnen.
Wenn es viele Konflikte gibt, kann das Zusammenführungsergebnis außerdem unvorhersehbar sein.
Dies ist jedoch nicht die einzig mögliche Strategie, und in diesem Artikel wird eine alternative Möglichkeit zur Verwaltung neuer Produktfunktionen ohne die oben aufgeführten Nachteile behandelt.
Laut Git-Design kommt es beim Zusammenführen zu Zusammenführungskonflikten, wenn Zweige in derselben Dateizeile unterschiedliche Inhalte haben.
Um dies zu veranschaulichen, betrachten wir ein Szenario, in dem zwei Teams Updates für denselben Dienst implementieren. Team A integriert die Kreditkartenunterstützung, während Team B die Benutzerprofilseite überarbeitet. Es scheint, dass diese Funktionen nichts miteinander zu tun haben.
Es stellte sich jedoch heraus, dass sich der zahlungsbezogene Code zuvor an derselben Stelle befand wie der Code der Profilseite. Also extrahierten beide Teams ihren Code in separate Zweige und schrieben die Integration neu.
Nun stellt sich die Frage: Wer wird als Erster seine Änderungen in den main
einbinden und so tun, als ob das Problem nicht auf seiner Seite liegt, während das andere Team versucht, den daraus resultierenden Konflikt zu lösen?
Insgesamt ist es unmöglich, Zusammenführungskonflikte zu vermeiden, aber wir können sie sicherlich einfacher lösen, indem wir die folgende bekannte Regel verwenden:
Wenn eine Aktion schwierig und beängstigend ist, führen Sie sie öfter aus
In Git-Begriffen würde dies bedeuten, dass wir so oft wie möglich zusammenführen müssen (idealerweise bei jedem Commit). Und natürlich wird es in diesem Fall häufiger zu Konflikten kommen, aber sie lassen sich viel einfacher lösen.
Man nennt es Trunk-basierte Entwicklung und bedeutet, Änderungen direkt in den main
zu übertragen und die Verwendung von Zweigen zu vermeiden, wenn sie unnötig sind.
Wenn im obigen Beispiel beide Teams ihre Änderungen regelmäßig in den main
übertragen würden, würden sie schnell bemerken, dass sie versuchten, dieselbe Datei zu ändern.
Darüber hinaus hätten sie Probleme ganz vermeiden können. Das zweite Team hätte mit den Änderungen begonnen, nachdem das erste Team die Datei unter Berücksichtigung dieser Aktualisierungen bereits geändert hatte.
Ein aufmerksamer Leser könnte sich fragen: Klingt alles großartig, aber wie gehen wir beim Testen vor? Zweige pro Feature ermöglichen das isolierte Testen der gesamten neuen Funktionalität vor der Veröffentlichung; Wenn wir Änderungen kontinuierlich in den main
integrieren, gibt es dafür keine Chance.
Ein Feature-Flag oder ein Feature-Toggle ist ein einfaches dynamisches Flag, das das Umschalten einer bestimmten Funktion zur Laufzeit ermöglicht. Im Allgemeinen ermöglichen Feature-Flags auch das Aktivieren oder Deaktivieren von Funktionen für bestimmte Benutzergruppen, z. B. QA-Ingenieure, Mitarbeiter, bestimmte Kunden usw.
Die Feature-Flags bieten mehrere zusätzliche Vorteile:
Durch die Verwendung von Feature-Flags wird das Pushen von Änderungen an den main
sicherer. Solange das Feature-Flag deaktiviert ist, wirken sich die Änderungen auf niemanden aus.
Diese Technik ermöglicht es, direkt mit dem main
zu arbeiten oder kurzlebige Zweige zu erstellen. Daher werden Zusammenführungskonflikte ziemlich selten und lösen sich schnell.
Zusammenfassend lässt sich sagen, dass die Trunk-basierte Entwicklung in Kombination mit Feature-Flags eine hervorragende Technik ist, die dabei hilft, viele Probleme zu vermeiden, die durch widersprüchliche Änderungen in Feature-Branches entstehen.
Allerdings gibt es wie immer keine Einheitslösung. Es funktioniert für eine kleine Anzahl von Teams, die im selben Repository arbeiten – eine Erhöhung dieser Anzahl erfordert normalerweise einige Anpassungen.
Darüber hinaus ist es immer möglich, beide Methoden zu verwenden: Verwenden Sie je nach Situation und Aufgabe Feature-Branches oder Feature-Flags.