Skip to content

Was mir an git gefällt

Nachdem ich mich jetzt bereits einige Wochen mit git auseinandersetze, ist es vielleicht einmal Zeit für ein Fazit. Ich mag mir kein fachkundiges Urteil über git erlauben; dazu fehlt mir der wirkliche Vergleich mit anderen Versionsverwaltungssystemen und die Erfahrung mit (gemeinsamer) Softwareentwicklung, und letztlich auch der wirklich "fortgeschrittene" Umgang mit git. Ich denke aber, daß ich - obschon ich git bisher "solo" nutze, also zu seinen Stärken und Schwächen bei der Zusammenarbeit selbst nichts sagen kann - durchaus einige Punkte benennen kann, die mir an git gut gefallen.

Da wäre auf den ersten Blick bereits die Verzeichnisstruktur: wo SVN mich mit trunk, tags und branches verwirrt, gibt es bei git ein Verzeichnis .git, und das war’s.

Auch zunächst eher eine Äußerlichkeit, aber sehr bequem, ist die Möglichkeit, mit git "offline" zu arbeiten. Bei git wird die Arbeitskopie nicht aus einem zentralen Repository ausgecheckt; vielmehr wird das zentrale Repository im Normalfall komplett kopiert und steht mir dann auch offline mit der gesamten Versionsgeschichte zur Verfügung. Das ermöglicht es überdies, neben einem "offiziellen" Repository - das im Netz steht - beliebig viele "inoffizielle" Repositories vorzuhalten. Änderungen kann ich so zunächst nur in meiner Kopie des Repositories vornehmen (und sie ggf. auf andere eigene Rechner spiegeln und auch mit anderen Entwicklern austauschen) und sie erst dann veröffentlichen, wenn ich sie für veröffentlichungsreif halte. So kann ich bspw. immer nur bestimmte Zweige meines Entwicklungsrepositories in ein öffentliches Repository übertragen und andere, an denen ich noch bastele, nicht veröffentlichen.

Das problemlose Anlegen von Kopien (Zweigen, branches) ist aus meiner Sicht ein weiterer Vorteil; ein Entwicklungszweig (branch) ist trivial und schnell angelegt und ebenso schnell auch wieder entfernt. Das ermöglich ein schmerzloses Ausprobieren von Änderungen jeder Art; man kann für jede Idee einfach einmal schnell einen neuen Zweig anlegen, sie ausprobieren und dann ggf. verwerfen oder auf Eis legen kann - oder in die "eigentliche" Entwicklungslinie übernehmen. Auch lassen sich so verschiedene Ideen einfach in verschiedenen Branches entwickeln und dann jederzeit direkt in den Hauptzweig übernehmen, oder man kann sie erst noch etwas "köcheln" lassen; daneben können verschiedene Entwicklungsstränge bspw. für eine geplante neue Version und für Bugfixes älterer Versionen nebeneinander laufen.

Ergänzend dazu fasziniert mich die Möglichkeit, meine Commits nachträglich nachzubessern und neu zu sortieren. Die Möglichkeit fraktionierter Commits hatte ich bereits angesprochen; außerdem kann ich jederzeit per interaktivem rebase einzelne Commits zusammenfassen. Oder ich setze einfach nur den Index auf eine alte Version zurück, so daß ich dann die Änderungen in der aktuellen Arbeitskopie gegenüber diesem alten Zustand neu einchecken kann, auch in einzelnen Teilen. In diese Reihe gehört auch die Möglichkeit, mein lokales Repository - oder einzelne Entwicklungszweige darin - immer wieder neu auf den aktuellen Stand des "offiziellen" Repositories - oder des Hauptentwicklungszweiges - aufsetzen zu lassen. All das ermöglicht es - auch zusammen mit dem leichten Anlegen neuer branches - auf der einen Seite, nahezu beliebig "herumzuspielen" und dabei dem Motto "Commit early, commit often" zu folgen, auf der anderern Seite aber später, wenn das Feature gereift ist, eine logische Abfolge von einzelnen Patches zu committen, die die ganzen Sackgassen und Fehlversuche auslässt und möglichst einfach nachzuvollziehen ist.

Um ein paar Beispiele für die Vorteile dieser Arbeitsweise zu nennen:

Ich kann zum Beispiel während der laufenden Entwicklung jeden Entwicklungszweig (branch) immer wieder periodisch neu auf den aktuellen Stand des Hauptzweigs (master branch) aufsetzen lassen (rebase); wenn die Entwicklung eines bestimmten Features dann reif ist, kann ich sie in den Hauptzweig übernehmen und habe dann nur genau diese Änderungen in der Versionsverwaltung stehen, und zwar ausgehend vom aktuellen Stand des Hauptzweigs. Statt rebase könnte ich natürlich auch merge benutzen, dann habe ich aber eine Unzahl von für das Verständnis überzähligen Commits in der Versionsgeschichte stehen.

Nehmen wir an, ich arbeite an einem bestimmten Feature und committe Änderungen oft und zeitnah (um sie ggf. wieder zurücknehmen zu können, wenn sich der Weg als Irrweg erweist). Irgendwann bin ich dann mit dem Sachstand zufrieden und halte das Feature für reif genug für das nächste Release. Jetzt könnte ich den Entwicklungszweig einfach in den Hauptzweig mergen; dann steht aber das gesamte hin und her in der Versionsgeschichte, was sie auf die Dauer eher unübersichtlich macht. Ich kann aber auch durch interaktives rebase und/oder durch ein reset zunächst den Entwicklungszweig neu zusammenstellen und entscheiden, in wie viele Commits in welcher Reihenfolge ich meine diversen Änderungen aufgeteilt haben möchte. Ich schreibe quasi rückblickend die Versionsgeschichte nachvollziehbar und ordentlich neu und merge dann eine logische Abfolge von einzelnen Schritten in den Hauptzweig. Das sieht nicht nur eleganter aus, es ist auch leichter verständlich.

Andersherum kann ich vorgenommene Änderungen auch sukzessive in mehreren Commits in die Versionsverwaltung schreiben. Angenommen, ich habe eine Website in einem git-Repository liegen und nehme umfangreiche Änderungen und Ergänzungen an einer Webseite vor. Bei dieser Gelegenheit fallen mir auch einige Rechtschreibfehler im bereits vorhandenen Text auf. Jetzt könnte ich entweder erst meine Änderungen und Ergänzungen abschließen, sie committen und dann in einem zweiten Schritt die Rechtschreibfehler beheben (wenn ich das nicht bis dahin vergessen habe). Oder ich behebe die Rechtschreibfehler nebenbei mit und committe sie zusammen mit den Änderungen; aber dann wird die commit message ein Gemischtwarenladen und ich kann v.a. meine Änderungen nicht isoliert reverten. Mit git kann ich die an der Arbeitskopie vorgenommenen Veränderungen stückchenweise committen: bspw. erst isoliert die Rechtschreibfehler, und dann - getrennt davon - die zeitgleich vorgenommenen Änderungen und Ergänzungen. Danach habe ich zwei getrennte Commits, die zwei logisch verschiedene Vorgänge getrennt wiedergeben und die auch getrennt zurückgenommen werden können.

Ich halte das - mit Vorsicht genutzt - für ein sehr interessantes Arbeitswerkzeug. "Mit Vorsicht genutzt" deshalb, weil es natürlich fatal ist, die Versionsgeschichte bereits veröffentlichter branches umzuschreiben … deshalb sollte man entweder nur die Entwicklungszweige öffentlich zugänglich machen, die man auch unverändert so stehenlassen möchte, oder wenigstens klar kommunizieren, welche Entwicklungszweige "work in progress" sind und keinesfalls für eigene Entwicklungszwecke gepullt werden sollen.

Trackbacks

Keine Trackbacks

Kommentare

Ansicht der Kommentare: Linear | Verschachtelt

Noch keine Kommentare

Kommentar schreiben

HTML-Tags werden in ihre Entities umgewandelt.
Markdown-Formatierung erlaubt
Standard-Text Smilies wie :-) und ;-) werden zu Bildern konvertiert.
BBCode-Formatierung erlaubt
Gravatar, Identicon/Ycon Autoren-Bilder werden unterstützt.
Formular-Optionen