Probleme mit DVCS

Wie Git und Mercurial Ihrem Code-Review schaden können

Marcin Kuzminski

© Shutterstock.com/Semmick Photo

Neben all ihren Bemühungen, Teams bei der Lieferung von mehr Commits zu unterstützen, haben Git und Mercurial doch ein bedeutendes Problem hervorgebracht: Die Verlangsamung der Peer Reviews. Marcin Kuzminski erläutert, wie „pragmatische Groupings“ Abhilfe schaffen können.

Vor fünf Jahren begann die Telekommunikationsfirma, bei der ich damals beschäftigt war, von Subversion zu verteilten Versionsverwaltungssystemen (distributed version control system, DVCS) wie Git und Mercurial zu wechseln. Die Vorteile waren gewaltig, aber wie so oft bei neuen und spannenden Dingen gab es auch Probleme.

Git und Mercurial eignen sich hervorragend dafür, Softwareentwicklern die Möglichkeit zu geben, regelmäßig und von überall her ihre Beiträge einzureichen. Die Erleichterung der Commits hat unserem Team erlaubt, sich von 5 auf 100 Commits pro Tag zu steigern. Doch dann bemerkten wir ein Problem: Die History der Commits zwecks Peer Review durchzugehen wurde schlicht zuviel. Unser Code Review büßte an Effizienz ein.

Schlussendlich entwickelten wir dann eine Technik, die ich „pragmatisches Grouping“ nenne. Sie kann sowohl mit Git als auch mit Mercurial angewendet werden und setzt keine spezielle Technologie voraus. Um loszulegen, müssen Sie lediglich Git oder Mercurial herunterladen. Bevor ich die Technik des pragmatischen Groupings erläutere, möchte ich jedoch zunächst die Gründe für meinen Abschied von Subversion nennen.

Die Grenzen von Subversion für New-School-Entwickler

Als unser Entwicklerteam noch Subversion nutzte, musste jeder mit dem Server verbunden sein, um am Projekt mitwirken zu können, was immer unpassender wurde, je mehr wir uns dezentralisierten. Weil sehr viele Leute an demselben Projekt arbeiteten, hatten wir ständig Probleme mit Merges und der Bereitstellung. In der Folge verschwendete unser Team viel zu viel Zeit mit der Reparatur von Merge-Problemen.

Wir wechselten dann zu einem modernen Entwicklungsmodell, in dessen Rahmen die Mitarbeiter so oft wie möglich committeten. Jeder Entwickler zeichnete dabei jeden noch so kleinen Schritt auf. Mit Subversion muss man jedoch ständig auf Commits warten. Wenn ein Anderer gerade mergt, kann es zu einem Konflikt kommen, mit der Folge, dass man mindestens eine Stunde allein damit verschwendet, die Merges durchzugehen. Und das kann jederzeit passieren.

Als sich der Entwicklungsprozess ändern sollte, war jedem klar, dass sich auch die Tools ändern mussten. Meine New-School-Kollegen und ich änderten unseren Workflow schneller als Suberversion sich daran anpassen konnte. Seitdem wir versuchten, so oft wie möglich – teilweise alle 15 Minuten – zu committen, waren wir in einer Art „Merge-Hölle“ gefangen. Man brauchte eine konstante Verbindung zum Büro und wegen ständiger Kommunikationsverzögerungen war die Arbeit von Zuhause ein einziger Albtraum.

Nicht vom Server abhängig sein

Wenn man nicht von einer Serververbindung abhängig ist, kann man oft schneller arbeiten. Darüber hinaus muss man nicht laufend nach einem Ort mit Internetzugang (oder einem VPN) suchen, um seine Commits einzureichen. Mit Git und Mercurial hat jeder, nicht nur der Server, ein komplettes Backup (Dateien, History).

Mit Git und Mercurial kann jeder der Server werden. Man kann seine Beiträge in hoher Regelmäßigkeit einstellen, ohne den Code anderer Entwickler zu zerstören. Commits sind lokal, man tritt also den anderen Entwicklern nicht auf die Füße. Man kann die Builds oder Umgebungen anderer Entwickler nicht mehr kaputt machen, nur indem man versucht zu committen. Leute ohne „commit access“ können Commits leisten (weil das committen in einem DVCS nicht notwendigerweise bedeutet, den Code hochzuladen).

So wird es erheblich vereinfacht, Beiträge zu leisten. Als Integrator kann man sich entscheiden, Änderungen aufzunehmen oder nicht. Mitwirkende können Teams bilden und das Merging selbst übernehmen, was weniger Arbeit für den Integrator bedeutet. Sie können außerdem ihre eigenen Branches haben, ohne Andere zu behindern (während sie aber gleichzeitig in der Lage sind, diese zu teilen). Weil ein DVCS Kommunikation unumgänglich macht, kann dieser neue Programmierstil überdies die natürliche Kommunikation fördern. In Subversion dagegen gibt es regelrechte Commit-Rennen, die zwar Kommunikation erforderlich machen, dies allerdings auch nur, weil sie die Arbeit behindern.

Die Anzahl der Commits geht durch die Decke

Andere Leute in meiner Firma haben nur einmal am Tag oder sogar nur einmal alle paar Tage committet. Oftmals arbeiteten diese Entwickler alleine an einem Projekt. An diesem Unterschied lässt sich gut erkennen, wie sehr die verschiedenen Workflows in kollaborativen Entwicklerteams divergieren können. Meiner Ansicht nach wird Zusammenarbeit in Zukunft noch wichtiger, ebenso wie häufigere Commits mit besserem Packaging oder Repräsentation einer Gruppe von Commits.

Die Frequenz der Commits und die Fähigkeit des Versionskontrollsystems, diese zu bewältigen, haben die Zusammenarbeit erheblich vereinfacht. Subversion jedoch trieb mein Entwicklerteam für Web- und Cloud-basierte Apps langsam in den Wahnsinn. Bei dem Versuch, Subversion an unseren neuen Entwicklungsprozess anzupassen, tauchten derart viele Probleme auf, dass wir uns genötigt sahen, einen unserer Entwickler nur für das Management von Subversion abzustellen. Daraufhin mussten wir immer warten, bis er die Probleme beheben konnte, weshalb wir oft genug nicht weiterarbeiten konnten. Da unser Entwicklungsstil von regelmäßigen Commits abhängig war, entstand durch die häufige Downtime große Frustration.

Heute committen wir pro Person zehn bis zwanzig Mal am Tag, manchmal schafft jemand sogar 60 Commits pro Tag. In einer kleinen Entwicklergruppe von fünf Personen kommen wir also auf 100 Commits pro Tag.

Die Commit-History zähmen

Zu unserem Best Practice gehört es, so oft wie möglich die Working Copy zu säubern. Jeder Entwickler markiert die Schritte, die er gebraucht hat, um von A nach B zu kommen. Die einzelnen Schritte überprüfen wir dann als eine große Änderung. Ich bezeichne diesen Workflow als „Pragmatic History“.

Wenn beispielsweise eine Person einen Pull Request mit zwanzig Commits um eine einzelne Idee herum macht, quetschen wir die Commits in einen Pragmatic. Das ist eine ungewöhnliche Vorgehensweise. Normalerweise werden zwanzig Commits in drei Pragmatics aufgeteilt, die typischerweise so aussehen:

  1. Testing
  2. Implementierung
  3. Dokumentation

Vermeiden Sie es, einen einzigen, bestimmten Weg zur Repräsentation des Workflows zu erzwingen. Stattdessen sollten Sie Entwicklern die Freiheit lassen, das zu tun, was sie für das Beste halten. Das ist besonders in großen Unternehmen wichtig, wo es üblich ist, gemischte Teams zu haben, die wiederum unterschiedliche Herangehensweisen pflegen.

Wenn Sie zum Beispiel einen Tippfehler in einem Dokument finden, ihn beseitigen und danach das gleiche noch einmal machen, sollten Sie eine Workflow-Politik durchsetzen, die besagt, dass solche Änderung doch bitte in einen Pragmatic gequetscht werden sollen. Wir sagen unseren Entwicklern, dass sie ein paar „pragmatische“ Schritte machen sollen. Diese Schritte waren entscheidend dafür, die nötige Funktionalität zu erreichen. Hier ist ein anderes Beispiel für eine Gruppe von Pragmatics:

  1. Die Funktion erstellt
  2. Die Funktion um zusätzliche Parametern erweitert
  3. Tests für die Funktion geschrieben

Auf diese Weise kann man regelmäßig committen, sich im Code-Review jedoch auf Pragmatics zu beziehen. Man nehme beispielsweise zwanzig Commits und verwandele sie in fünf klare, pragmatische Schritte. Dabei sollte man Schritte wie „Ich habe einen Schreibfehler korrigiert“ der „Ich habe eine Funktion umbenannt“ vermeiden, da sie für den Code-Review-Prozess nicht hilfreich sind.

Bei dieser pragmatischen History handelt es sich um einen Workflow, den ich nach jahrelanger, intensiver Nutzung von Versionskontrollsystemen entwickelt habe und immer noch benutze. Sowohl Mercurial als auch Git unterstützen History-Edits. Wenn Personen aus meinem Team den Code mit Mercurial oder Git abnehmen, legen sie eine Notiz an, damit die Commits in einige wenige Schritte gepresst werden. Ihren Code ordnet ein Entwickler dann in einer kleineren Gruppe von Pragmatics an und ich brauche nur noch einen Button zu drücken, um die Änderungen zu akzeptieren.

Diese Technik erlaubt es, Dinge wie etwa Bisect zu tun. Wenn Sie beispielsweise versuchen, retroaktiv die Stelle zu finden, an der ein Bug eingefügt wurde, können Sie sich klar abgegrenzte Schritte anschauen. Jeder dieser Schritte deckt einen bestimmten Bereich der Arbeitsfunktionalität ab. Man kann dann einfach jeden der Schritte auswählen, sich umschauen und den kleineren Schritt identifizieren, der das Problem verursacht hat.

Dadurch wird die Bearbeitung der Commit-History ebenfalls wesentlich effizienter, was für den neuen Stil dezentraler Entwicklerteams unverzichtbar ist.

Sobald ich fünfzig Mal „Tippfehler entfernt“ gelesen habe, wird es langweilig und ich verliere die Motivation, mich richtig im Code einzugraben. Entwickler fragen sich vielleicht, „warum soll ich die Commit-History überhaupt lesen?“ Indem man die Commits in Pragmatics gruppiert, wir die History viel leichter zu lesen, was die Arbeit für jeden Entwickler angenehmer macht und Ihr Team bedeutend effizienter werden lässt.

Fazit

Als ich erstmals damit anfing, neue Tools wie Mercurial oder Git zu benutzen, erkannte ich schnell, dass sie die quälenden Probleme von Subversion lösen konnten. Das war sehr aufregend, weil jedes Mitglied so oft es wollte committen konnte – ganz gleich, ob sie online oder offline waren. Sowohl die Merges als auch die komplette History sahen mit Mercurial und Git viel besser aus. Beide Systeme waren allgemein schneller und ließen uns viel produktiver werden.

Meine Geschichte des pragmatischen Workflows zeigt, was wir tun mussten, um die History einer großen Anzahl von Commits zu bewältigen. Solange wir noch mit Subversion arbeiteten und nur sehr wenig committen konnten, gab es dieses Problem nicht. Als wir aber anfingen, kollaborativer zu arbeiten, stieg die Zahl der Commits gewaltig an und wir bekamen Probleme mit Subversion. Als wir Subversion hinter uns zu ließen, entstanden aber neue Herausforderungen. Eine davon war, einen Weg zu finden, mit den vielen Commits umzugehen. Eine Veränderung im Management des Workflows konnte diese Probleme lösen.

Aufmacherbild: Worded marking SLOW painted on the road von Shutterstock.com / Urheberrecht: Semmick Photo

Verwandte Themen:

Geschrieben von
Marcin Kuzminski
Marcin Kuzminski
Marcin is a Python enthusiast, open source evangelist, and co-founder of RhodeCode, Inc. In addition to Python, Marcin has extensive experience with JavaScript, Java, Ruby, and C++. He's worked as a software developer and CTO in Poland, Israel, Germany, and USA. In his spare time, Marcin has been heavily involved in many open source projects including; RhodeCode, VCS, Celery, Pyramid, Mercurial, Dulwich, Salt, and Libcloud.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: