blog · git · desktop · images · contact


Schöne neue Welt: Verteilte Versionskontrolle

2008-08-18

Software zur Versionierung ist eine tolle Sache. Man kann den aktuellen Stand in ein Repository einchecken und dann munter weiterschaffen, ohne Angst davor haben zu müssen, alles mit Änderungen kaputt zu machen, die man nicht mehr rückgängig machen kann. Im Zweifelsfalle springt man einfach zu einer älteren, noch lauffähigen Version zurück.

Es wurde nun allerhöchste Eisenbahn, dass ich mir endlich mal die verteilten Versionskontrollsysteme näher anschaute. Wie sich herausgestellt hat, hätte ich das auch schon viel früher tun sollen, denn diese Tools sind eine äußerst praktische Sache.

Meine beiden Schwerpunkte sind einfache Benutzung und einfache Einrichtung. Anders formuliert: Ich will so wenig wie möglich tun müssen, um ein Projekt versionieren zu können - aber ohne dabei die Möglichkeit zu verlieren, es in einer solchen Form irgendwo zu veröffentlichen, dass jemand anderes mit einsteigen kann.

In die nähere Auswahl fielen letztendlich Git, Mercurial und Bazaar.

Machen wir's kurz: Bazaar hat gewonnen. ;) Im Folgenden also die Punkte, die es von den anderen beiden abgrenzen und die ich - für meine Zwecke - als eindeutige Vorteile ansehe. Großartig Begriffe und Vorgehensweise werde ich aber nicht erklären - schon alleine, weil diese sich zwischen den einzelnen Programmen durchaus unterscheiden.

Bedienung und Branching

Zugegebenermaßen ist die Bedienung aller drei Programme ziemlich einfach. Mit "bzr init" initialisiert man ein Verzeichnis als Repository, komplett analog geht es mit "git init" oder "hg init". Dateien bringt man dann mit "bzr add xyz" in die Verwaltung oder eben "git add xyz" respektive "hg add xyz". Syntax für Commits ist auch quasi identisch. Big deal.

Der erste große Unterschied ist mir beim Branching aufgefallen. Mit "git branch neuerZweig" erstellt man hier einen neuen Branch (Oha!), der sich aber im selben Verzeichnis befindet. Ein einfaches "git branch" listet alle bekannten Branches auf, der momentan aktive ist mit einem Sternchen gekennzeichnet. "git checkout irgendwas" wechselt zum Branch "irgendwas". Gefiel mir eigentlich auf Anhieb. Bei Mercurial läuft es ähnlich, die Ausgabe des Programms erschien mir aber unübersichtlicher.

Bazaar ist da etwas anders, denn hier kommt das Erstellen eines neuen Branches mittels "bzr branch . neuerZweig" faktisch dem Klonen des Repositorys bei Git gleich. Die "normale" Vorgehensweise bei Bazaar klont also immer und erstellt neue Verzeichnisse, stattdessen liegen nach Voreinstellung alle Branches bei Git und Mercurial in einem Verzeichnis. Man wechselt hier mit Kommandos der Programme die Branches, wohingegen man das bei Bazaar durch einen Verzeichniswechsel erledigt.

Das erscheint auf den ersten Blick eigentlich als Nachteil, weil es doch ziemlich mühselig ist, für jeden Branch ein eigenes Verzeichnis zu haben. Da ist ein großes Repository, das alle lokalen Branches vereint, übersichtlicher. Einen Unterschied macht das aber, wenn man sein Repository irgendwo publik macht. Hier nämlich ist bei Bazaar ziemlich offensichtlich, dass ich zweimal publizieren muss, wenn ich zwei Branches habe! Bei Git hatte ich erwartet, dass mit einmaligem Publizieren auch gleich beide Branches drin sind - Fehlanzeige. Auch, wenn ich mich aktuell im Verzeichnis meines Repositories befinde, kann ich dieses nicht auf einen Schlag mit allen Branches "exportieren", sondern muss das für jeden Branch einzeln tun. Vielleicht erreicht man es über Umwege oder andere Vorgehensweise zwar, dann spricht das aber trotzdem gegen Git, denn Bazaar ist hier einfach straightforward. Mit Mercurial habe ich in dieser Hinsicht gar nicht länger rumprobiert, da hier das Vorgehen noch verwirrender ist.

Output

Großer Pluspunkt für Git: Alle Ausgaben werden per Default an "less" gepiped. Das ist äußerst praktisch und das habe ich bei Bazaar nur durch Plugins erreichen können.

Aber: Bazaar hat den übersichtlichsten Log-Output aller drei Programme. Einfach mal ein paar Beispiele: Ich habe zwei Branches, "trunk" und "dev". Jeweils in "trunk" einen initialen Commit, dann erfolgt der Branch zu "dev", dort ein paar Änderungen und dann werden diese in "trunk" gemerged.

git

commit 6aeec276e7bef6e1976fbcd8292235730faaf1ac
Author: Ich <ich@example.invalid>
Date:   Mon Aug 18 19:32:36 2008 +0200

    Noch einmal in "dev"

commit 7e6b84b075b9abcc4a319026a5566ee3d1598e23
Author: Ich <ich@example.invalid>
Date:   Mon Aug 18 19:32:25 2008 +0200

    Erste Änderung in "dev"

commit 47886db09f009640eca6170069e22af5a346d029
Author: Ich <ich@example.invalid>
Date:   Mon Aug 18 19:31:51 2008 +0200

    Initialer Commit

Hier fällt schon einmal auf, dass Git auf einen zusätzlichen Commit nach dem Merge verzichtet. Prinzipiell ist das auch in Ordnung so, denn man kommt immernoch an alle alten Versionen ran. Aber man hat eben auch keine Möglichkeit, dazu einen Kommentar zu geben. Auch weiß ich nicht, wer diesen Merge denn überhaupt durchgeführt hat. Irgendwie fehlt mir auch eine Angabe, was aus welchem Branch kam.

hg

changeset:   3:f2a6ae3897db
tag:         tip
parent:      0:042a87504745
parent:      2:9e216bb73056
user:        ich@example.invalid
date:        Mon Aug 18 19:37:55 2008 +0200
summary:     "dev" dazugemerged

changeset:   2:9e216bb73056
branch:      dev
user:        ich@example.invalid
date:        Mon Aug 18 19:35:49 2008 +0200
summary:     Zweite Änderung in "dev"

changeset:   1:34bd8dbe161e
branch:      dev
user:        ich@example.invalid
date:        Mon Aug 18 19:35:39 2008 +0200
summary:     Erste Änderungn in "dev"...

changeset:   0:042a87504745
user:        ich@example.invalid
date:        Mon Aug 18 19:35:06 2008 +0200
summary:     Initialer Commit

Naja, dazu gibt es nicht viel zu sagen. Durchwachsen. Es steht alles Wichtige da, aber besonders übersichtlich ist es auch nicht.

bzr

------------------------------------------------------------
revno: 2
committer: Ich <ich@example.invalid>
branch nick: trunk
timestamp: Mon 2008-08-18 19:40:21 +0200
message:
  "dev"-Zweig zum Hauptzweig gemerged
    ------------------------------------------------------------
    revno: 1.1.2
    committer: Ich <ich@example.invalid>
    branch nick: dev
    timestamp: Mon 2008-08-18 19:40:09 +0200
    message:
      Zweite Änderung...
    ------------------------------------------------------------
    revno: 1.1.1
    committer: Ich <ich@example.invalid>
    branch nick: dev
    timestamp: Mon 2008-08-18 19:39:49 +0200
    message:
      Erste Änderung in "dev"
------------------------------------------------------------
revno: 1
committer: Ich <ich@example.invalid>
branch nick: trunk
timestamp: Mon 2008-08-18 19:39:28 +0200
message:
  Initialer Commit

Ich denke, es ist auf Anhieb klar, was ich meine. Dieses Prinzip der einfachen Lesbarkeit und Übersichtlichkeit zieht sich auch durch alle Ausgaben von Bazaar, es ist nicht nur auf die Log beschränkt.

Veröffentlichungen

Git und Mercurial benötigen beide auf Seite des Servers zusätzliche Software, um komfortabel ein Repository dort zu erstellen und betreiben. Das bedeutet zusätzlichen Einrichtungs- und Wartungsaufwand, sowie zusätzliche Angriffsvektoren. Fairerweise muss man dazusagen, dass beide auch von lokal auf dem Rechner befindlichen Repositories "pullen" beziehungsweise dort hin "pushen" können. Somit kann man über SSHFS mit reinem SSH-Zugang auf irgendeinem Server ein Repository betreiben. Auf der anderen Seite bedeutet das jedoch wieder zusätzlichen Aufwand auf der Seite des Clients.

Hier kommt nun der, in meinen Augen, größte Vorteil von Bazaar ins Spiel, denn dieses unterstützt von Haus aus Repositories auf entfernten Servern, die über reines SSH/SFTP "bedient" werden: "bzr push sftp://user@host/pfad/" und fertig. Man muss keinerlei neue Software am Server installieren, um seine Sachen zu veröffentlichen und zu pflegen. Hat man irgendwo SSH-Zugang, so hat man ("in der Regel") auch SFTP-Zugang und schon kann man hier ein Bazaar-Repository eröffnen. Hat man dort Schreibzugriff auf Verzeichnisse, die von einem Webserver gelesen werden, kann man also auch auf einfachste Weise anderen Zugang zu den eigenen Projekten gewähren.

Die Kehrseite davon ist natürlich die Geschwindigkeit. Pullen und Pushen über SFTP dauert definitiv länger als die entsprechenden Vorgänge bei den "nativen" Servern von Git und Mercurial. Andererseits gibt es auch einen kleinen Bazaar-Server, den ich aber nicht ausprobiert habe, da ich ihn nicht benötige.

Fazit: Ideal für kleine Projekte

... und in kleinen Umgebungen. Wie sich Bazaar bei sehr großen Projekten verhält oder ob es zum Beispiel an der Uni statt dem weit verbreiteten SVN eingesetzt werden könnte, kann ich noch nicht abschätzen. Im Moment ist das aber auch irrelevant für mich. Es geht mir, wie eingangs erwähnt, um möglichst einfache Versionierung und Veröffentlichung kleiner Projekte. Diese Aufgabe meistert Bazaar auch sehr gut, da es einfach total straightforward ist und die Anzahl an Überraschungen minimal hält.

Ich denke, Bazaar wird mir in Zukunft das Leben wesentlich einfacher machen.

Abschließend möchte ich noch sagen, dass ich keinesfalls behaupte, Experte in allen drei Programmen zu sein. Wenn dir etwas auffällt, das grundlegend falsch ist oder das man doch irgendwie einfacher erreichen kann, wäre ich um eine Korrektur oder Ergänzung natürlich sehr dankbar. :)

Comments?