Der Wechsel eines Versionskontrollsystems ist in der Softwareentwicklung immer ein brisantes Thema. Hinzu kommt, dass derartige Wechsel nicht sehr häufig passieren. In meiner doch schon länger anhaltenden IT-Laufbahn seit Ende der 90er gab es für mich diverse Versionskontrollsysteme:  cvs, Subversion, Mercurial, git und entsprechenden Moves (Migrationen).

Da besteht also kaum ein Wiederholungseffekt, geschweige denn ein Trainingseffekt oder gar Routine.

git-Move, Migration auf git als Versionskontrollsystem

Wie solch ein Wechsel ohne große Reibungsverluste und unter dem Druck des Projekt- und Tagesgeschäftes aussehen kann, möchte ich hier exemplarisch aufzeigen.

Wie es begann…

Subversion (svn) als Versionskontrollsystem ist nicht mehr State of the art und das auch schon etwas länger. Trotzdem sind manche Unternehmen noch auf betagteren Versionskontrollsystemen unterwegs und möchten gern auf ein aktuelleres System umsteigen. Doch hier stellen sich schnell Fragen:

  • Wie machen wir das?
  • Wann ist ein guter Zeitpunkt?
  • Wie schulen wir die Mitarbeitenden zeitnah?
  • Passen wir Prozesse gleich mit an, sodass manches vielleicht vereinfacht werden kann?
  • Welches Know-how benötigen wir personell dafür?
  • Ändern wir auch gleich die Versioniserung mit?

Fragen über Fragen und dies bei geringer Expertise für Migrationen. Entsprechend schnell wird die Umstellung gescheut und häufig kommt gern auch ein anderes Thema dazwischen, weil es wichtiger ist. So verzögert sich eine Umstellung …

Auch bei uns war es ähnlich:

  • Die Build-Tool-Umstellung auf Gradle war wichtiger, weil hier die Zeitersparnis viel deutlicher war.
  • Der Umstieg in die on-premise-Cloud war wichtiger, weil der Mehrwert für das Produkt höher war.
  • Dies und das war wichtiger, weil …

Alles nachvollziehbar, aber irgendwann ging es los.

Ein unmerklicher Einstieg

Als wir begannen, war der Einstieg nebenläufig und eher unbemerkt. Wir installierten uns einen git-Server und stellten erste Repositories für kleinere Tools bereit. Das wuchs stetig an und andere interne Tools wurden unmerklich von svn auf git migriert.

Im Tagesgeschäft für unser Hauptprodukt war das kein Thema und unbedeutend. Trotzdem hatte es einen positiven Einfluss auf:

  • die wenigen Entwickler, die bereits auf git umgestiegen sind. Sie sind bereit für den Umstieg und kennen git als Tool, können als Know-how-Multiplikator für ihre Team-Kollegen dienen.
  • das Team, welches die Infrastruktur betreut inklusive des zugehörigen git-Servers sowie den notwendigen Berechtigungen. Es kennt bereits wichtige Thematiken für die ‚große‘ Migration.

Es entwickelte sich ein Erfahrungsschatz und dieser gab Sicherheit und Vertrauen in der Benutzung und Betreuung von git. Konzepte zur Backupstrategie und Security wurden kleinteilig umgesetzt. Mit Blick auf die große Migration wurde auf die Anwendbarkeit der Konzepte bereits frühzeitig geachtet und gegebenenfalls zeitnah nachgebessert. Das lief über ein bis zwei Jahre so nebenher. Da sich andere Themen immer wieder vordrängelten, war da kein besonderer Druck.

Nutzung von Erfahrungen

Mit diesen ersten wertvollen Erfahrungen sowie dem Know-how um die aktuellen Anforderungen des Kernproduktes im alten Versionskontrollsystem konnten wir mögliche Probleme für die Migration besser beurteilen und im Vorfeld angehen und beseitigen.

Beispiele hierfür:

  • Anpassungen im Buildsystem für die direkte Verwendung von Versionskontrollsystemaufrufen. Hier ist es einmal die Identifikation der gesamten Stellen im Code sowie die Beseitigung oder Umstellung auf einen generellen Ansatz für Benutzung beider Versionskontrollsysteme. Zum Beispiel kann das Versionskontrollsystem im Jenkins auf einer höheren Ebene abstrahiert werden, Stichwort Jenkins SCM. Das heißt, es gibt keine direkten svn- oder git-Aufrufe, die Umstellung und spätere Wartung wird einfacher.
  • Die Dokumentationserstellung hat bei uns direkten Bezug zum Versionskontrollsystem. Hier sind zwar keine gravierenden Probleme zu erwarten, aber gegebenenfalls bedarf es anderer Ansätze, die Dokumentation automatisiert zu erzeugen. svn diff zwischen Versionen sind zum Beispiel Altlasten, die bei einer Migration beseitigt werden sollten.
  • Beim vorherigen Branchmodell ist direkt zu hinterfragen, inwieweit dies zu den Workflows in git passt und welche Konsequenzen sich daraus in den Prozessen um die Wertschöpfungskette ergeben. Gerade hier sind Störungen und Einwände der Beteiligten vorprogrammiert und dürfen nicht außer Acht gelassen werden. Da ist ein erheblicher Abstimmungsaufwand einzuplannen.
  • Analog zu den Änderungen am Branchmodell ist auch die Versionierung ein wichtiges Thema für uns, da die Versionierung in der svn-Welt bei uns nicht SemVer-konform war und dies zugleich ein Akzeptanzkriterium für die Umstellung darstellte. Natürlich hat dieser Umstand nur etwas bedingt mit der git-Migration zu tun. Schließlich hätte die Umstellung der Versionierung auch im Vorwege oder im Nachhinein passieren können.
    Wir hatten den klaren Anspruch, dies bei der Migration glatt zu ziehen und ohne technische Schulden auszukommen. Für die Prozesse um die Wertschöpfungskette herum bedeutete dies eine gravierende Änderung mit hoher Strahlkraft und Außenwirkung.
Branch- und Versionierungsmodell vorher und nachher

Wie unschwer zu erwarten war, kommt der Umstellung des Branchmodells und der zugehörigen Versionierung eine extrem hohe Bedeutung zu. Um die Herangehensweise zu verdeutlichen, folgt eine kurze Einführung in unser altes Branch- und Versionierungsmodell und das neue, vereinfachte git-Branchmodell rechts daneben.

Im Bild ist im svn-Teil links der Hauptentwicklungsbranch trunk zu erkennen, der eins zu eins auf den develop-Branch in git mappt. Der Unterschied bei den Prozessen liegt hier hauptsächlich darin, dass wir die bei uns vorhandenen wöchentliche Zwischenreleases nicht mehr extra abbranchen, sondern direkt vom develop-Branch bereitstellen. Ein analoges Vorgehen gibt es auch für die Release-Candidaten (RC-Branch, zukünftiger Produktions-Branch), die geplant alle zwei Monate neu entstehen.

Vereinfachung des Versions- und Branchmodells

Die Abschaffung dieses Vorgehens erspart der Entwicklerschaft einerseits Zeit, da nicht noch extra auf diese Branches merged werden muss, andererseits vereinfacht es die Anschaulichkeit des Gesamtprozesses und fördert das KISS-Prinzip. Der vermutete Mehrwert des Abbranches für die wöchentlichen Bereitstellungen ist seit Jahren nicht eingetreten und kann gegebenenfalls durch ein Revert von problematischen Änderungen auch direkt auf dem RC-Branch kompensiert werden.

In dem Zuge ließ sich auch die Versionierung stringenter und klarer durchziehen, da die gesonderte Versionierung für die Wochenbranches wegfiel. Insgesamt also eine deutliche Vereinfachung für die Zukunft und eine Ersparnis bei der Umsetzung.

Dieses Konzept hat sich in vielen Abstimmungsrunden und bei kritischen Nachfragen weiter entwickelt und als tragfähig erwiesen. Darauf basierend sind erste Prototypen entstanden, die immer weiter verfeinert wurden und vor der eigentlichen Migration bereits zur Verfügung standen, sodass sich dies jeder am echten Objekt ansehen und Testinstanzen wie zum Beispiel des Bugtrackingsystems anbinden konnte und das ohne Zeitdruck.

Trotzdem wurde zunächst weiterhin auf Basis von svn entwickelt. Allerdings standen die Migrationsskripte fertig bereit und der Source-Code wurde automatisiert alle paar Minuten samt der notwendigen Build- und Deploymentstrecke in die neue git-Welt (noch read-only) migriert. Es entstand eine Parallelwelt mit Produktivcharakter. Diese Parallelwelt lief permanent mit und etwaig auftretende Probleme konnten bereits identifiziert und gelöst werden. Das Risiko der Umstellung wurde dadurch beherrschbar für die gesamte Wertschöpfungskette inklusive der zugehörigen Prozesse.

Finale Schritte vor dem Start der Migration

Nachdem nun der Weg wie migriert werden soll und die zugehörigen Abläufe und Prozesse soweit fertig waren, lag der Schwerpunkt auf dem Zeitpunkt der Migration sowie dem Umfang. Ja, richtig gelesen: ‚dem Umfang‘.

Hier ist tatsächlich ein gewichtiger Unterschied zu meinen bisherigen Erfahrungen. Üblich wäre zu einem ‚Zeitpunkt X wird alles umgestellt‘, Stichwort ‚Big-Bang‘-Szenario und die entsprechenden Systeme laufen dann sofort ganz anders. Dem ist hier nicht so und das ist DER springende Punkt.

Wir haben aufgrund des gewählten Ansatzes und der bei uns vorhandenen Voraussetzungen die Möglichkeit, nur bestimmte Branches zu migrieren und somit bezogen auf den Lebenszyklus des Kernproduktes den Umfang steuern zu können.

Sanfte Migration durch begrenzten Umfang

Doch was bedeutet Umfang bei diesem Vorgehen? Es handelt sich natürlich um die Hauptentwicklungsbranches trunk/develop und die RC-Branches plus den Produktiv-Branch. Die bei uns verwendeten Feature-Branches lasse ich außen vor, sind aber genauso zu handhaben. Jeder Branch kann einzeln migriert werden.

Betrachten wir den Lebenzyklus des Hauptentwicklungsbranches, ist dieser abhängig vom Takt des Kernproduktes und liegt bei uns bei zwei Monaten. Alle zwei Monate gibt es ein routinemäßiges Release, Hotfixes sind natürlich trotzdem möglich.

Schrittweise Migration auf Branch-Ebene

In diesem Zwei-Monats-Takt begannen wir mit trunk/develop und einer Teil-Migration. Das heißt, ab Beginn einer neuen Entwicklungs-/Releaseperiode starteten wir mit einem migrierten trunk-Stand in die git-Welt. In der svn-Welt wurde der trunk-Branch gesperrt, sodass keine Commits auf dem svn-trunk-Branch mehr möglich waren. Der baugleiche neu migrierte develop-Branch in git wurde führend für jegliche Neuentwicklung. Hierauf basierend konnten dann auch Feature-Branches neu angelegt werden und alles Weitere passiert mit den git-Tools. Sukzessiv gelangte die Entwicklerschaft in die git-Welt und löst sich langsam von der alten svn-Welt. Alles ohne Zeitdruck und passend zur Arbeitsbelastung in den Entwicklungsteams.

Die anderen beiden Hauptentwicklingsbranches RC-Branch und Produktiv-Branch verblieben unter svn-Kontrolle sowie deren schon bestehenden Feature-Branches. Die Entwicklungsteams beendeten ihre Arbeit wie gewohnt und hatten keine Unterbrechungen durch Migrationen ihrer Branches. Zwei Monate nach dem Start der trunk-Migration wurde der RC-Branch in svn zum Produktiv-Branch und der git-develop-Branch zum neuen RC-Branch. Übrig blieb jetzt nur noch der Produktiv-Branch in svn und zugehörige Hotfix-Branches. Nach zwei weiteren Monaten erfolgt dieses Prozedere wieder und alle Hauptentwicklungsbranches sind unter git-Kontrolle, svn ist Geschichte!

Dieser Zeitpunkt war Anfang Februar. Somit sind nun alle Branches in der git-Welt angekommen und entsprechende Nacharbeiten zur Beseitigung der svn-Welt können starten.

Der geneigte Leser fragt sich hier sicher, wie kamen denn Fixes aus der alten svn-Welt noch einfach in die git-Welt beziehungsweise auf den develop-Branch? Hierfür wurden auch die svn-basierenden Hauptentwicklungsbranches permanent inkrementell migriert und Änderungen konnten per Cherry-Pick direkt auf den develop-Branch angewendet werden. Dies ist ein sehr einfaches Verfahren in der Umsetzung.

Wo lag für uns als Unternehmen der Vorteil dieser Art der sanften Umstellung?

Gegenüber einer klassischen Migration ‚Wir migrieren alles auf einmal‘ gab es für uns mehrere Vorteile:

  • Zum Jahresende sind wir immer in einer fachlich heißen Phase für die Featureentwicklung, die nicht gestört werden sollte. Dies hätte bei einer klassischen Migration zur Folge, dass wir mindestens noch zwei Monate mit dem Migrationsstart hätten pausieren müssten.
  • Da nur einige Entwicklungsteams von der initialen trunk-Migration betroffen waren, konnten wir gestuft schulen und dies auch genau bei den Teams, die etwas weniger unter zeitlichem Druck standen.
  • Wir wuchsen sanft in die migrierte Welt hinein. Kein Big-Bang-Risiko, es lief smooth!
  • Betrachten wir die geplanten zwei monatlichen Releases und die zugehörigen Prozesse, haben wir parallel dazu die Möglichkeit gehabt, Störungen zu fixen oder sogar Prozesse ohne großen zeitlichen Druck zu vereinfachen. Das half, den davon abhängigen Teams und dem Kunden Vertrauen in die neuen Prozesse zu fassen und sich daran zu gewöhnen.
  • Mit der agilen Brille betrachtet, konnten wir auf diese Art schneller einen Mehrwert durch die git-Migration bei gleicher oder besserer Qualität liefern. Dies ohne den fachlichen Entwicklungsteams unnötig Hindernisse bzw. Verzögerungen aufzubürden.

Aktuell haben wir die git-Migration sehr sanft hinter uns gebracht. Am Wochenende wurde aus dem RC-Branch der erste Produktiv-Branch. Störungen sind nicht zu erkennen. Und selbst dann sind diese ohne großen zeitlichen Druck lösbar. Aufregende Wochenenden wie bei vorherigen Umstellungen und typisch für ein ‚Big-Bang‘-Szenario hatten wir nicht – auch nicht das Daumendrücken und Hoffen, dass alles gut geht. Es war einfach nur ruhig, ein sanfter Wechsel des Versionskontrollsystems. I like to move it, move it

In diesem Sinne wünsche ich allen, die eine Migration des Versionskontrollsystem noch vor sich haben, ruhige Nächte, und vielleicht hilft dieser Artikel, die Herausforderung einmal anders anzugehen.

Frank Grzesiak-Mau