Versionsverwaltung

Eine Versionsverwaltung[33] (en. Version Control) ist eine Kombination verschiedener Techniken und Verfahren um Änderung an den Dateien eines Projekts, insbesondere Quellcode, Dokumentation und Webseiten, zu verfolgen und verwalten. Wenn Sie Versionsverwaltung noch nie benutzt haben, sollten Sie sich als Erstes jemand suchen die es kennt und sie überreden dem Projekt beizutreten. Heutzutage wird jeder erwarten, dass zumindest Ihr Quellcode unter Versionsverwaltung steht und keiner wird Ihr Projekt ernst nehmen, wenn es nicht zumindest halbwegs kompetent mit seiner Versionsverwaltung umgeht.

Versionsverwaltung ist beim Betrieb eines Projekts allgegenwärtig, weile es in nahezu jedem Bereich hilft: Kommunikation unter den Entwicklern, Veröffentlichung neuer Versionen, Bug-Verwaltung, Code-Stabilität und experimentelle Entwicklungen sowie die Annahme von und Anerkennung für Änderungen durch bestimmte Entwickler. Die Versionsverwaltung kann all diese Bereiche zentral koordinieren. Der Kern der Versionsverwaltung ist die Verwaltung von Änderungen (en. change management: Sie identifiziert jede einzelne Änderung an den Dateien eines Projekts, fügt ihnen Metadaten bei, wie das Datum der Änderung, den Namen des Autors und kann jedem der danach sucht, diese auf die gewünschte Art aufbereiten. Sie ist eine Methode zur Kommunikation, bei dem eine Änderung die grundlegende Einheit der Information ist.

Dieser Abschnitt behandelt nicht alle Aspekte der Bedienung einer Versionsverwaltung. Dieses Thema ist derart umfassend, dass es im Verlaufe des Buchs immer wieder angesprochen werden muss. Hier werden wir uns darauf konzentrieren ein Versionsverwaltung auszuwählen und einzurichten, die später die gemeinschaftliche Entwicklung unterstützt.

Vokabular der Versionsverwaltung

Dieses Buch kann Ihnen die Bedienung einer Versionsverwaltung nicht beibringen ohne vorherige Erfahrung, es wäre aber unmöglich das Thema zu behandeln, ohne ein paar Begriffe zu klären. Diese sind unabhängig von der eingesetzten Versionsverwaltung: Sie sind die grundsätzlichen Nomen und Verben der gemeinsamen Arbeit im Netzwerk und sie werden immer wieder im Verlaufe des Buches aufkommen. Selbst wenn es keine Versionsverwaltung gäbe, bestünde das Problem der Verwaltung von Änderungen und diese Wörter geben uns eine Sprache um präzise und prägnant über das Problem zu reden.

Commit

Eine Änderung an dem Projekt vornehmen; formeller gesagt, eine Änderung in die Versionsverwaltung zu speichern, sodass es in zukünftige Versionen des Projekts eingebunden werden kann. "Commit" (de. festlegen) kann als Nomen oder als Verb benutzt werden. Als Nomen ist es im wesentlichen ein Synonym für Änderung. Beispiel: "Ich habe eben einen Bugfix der bei Nutzern von Max OS X, Abstürze ihrer Server verursacht hat committed, Jay könntest du dir bitte den Commit anschauen und überprüfen, dass ich dort mit der Speicher Zuweisung nicht falsch umgehe?"

Commit-Log

Ein Kommentar der an jedem Commit angehängt wird, mit einer Beschreibung über die Änderung und sein Nutzen. Commit-Kommentare sind mitunter die wichtigsten Dokumente in einem Projekt: Sie sind die Brücke zwischen der äußerst technischen Sprache der einzelnen Änderungen am Code und der eher Nutzer orientierten Sprache der Funktionen, Bugfixes und dem Projektfortschritt. Später in diesem Abschnitt werden wir uns Möglichkeiten anschauen, Commit-Logs für das entsprechend angemessene Publikum zu veröffentlichen; ebenso sind in „Festschreiben von Traditionen“ im Kapitel Kapitel 6, Kommunikation Methoden beschrieben, Beteiligte dazu anzuregen, kurze prägnante und nützliche Commit-Kommentare zu schreiben.

Update

Eine Anfrage die Änderungen (Commits) anderer Teilnehmer in die eigenen lokalen Kopie des Projekts einzubinden; bzw. Ihre Kopie zu aktualisieren. Dies ist ein sehr häufiger Vorgang; die meisten Entwickler aktualisieren ihren Code mehrmals am Tag um sicherzustellen, dass sie ungefähr das Gleiche benutzen, wie die anderen Entwickler und beim Auffinden eines Fehlers sicher sein zu können, dass er noch nicht behoben wurde. z.B.: "Hallo, ich habe bemerkt, dass der Code für die Indexierung immer das letzte Byte fallen lässt. Ist das ein neuer Bug?". "Ja, aber er wurde letzte Woche behoben – versuch mal ein Update zu machen, dann sollte er verschwinden."

Projektarchiv

Die Datenbank der Versionsverwaltung in der Änderungen gespeichert werden. Manche Systeme sind zentralisiert: Es gibt ein Projektarchiv, in dem alle Änderungen am Projekt gespeichert werden. Andere sind dezentralisiert: dort hat jeder Entwickler sein eigenes Projektarchiv, und Änderungen können beliebig hin und her getauscht werden. Die Versionsverwaltung verfolgt die Abhängigkeiten zwischen den Änderungen und wenn es Zeit wird, eine neue Version zu herauszugeben, bekommt ein bestimmter Satz von Änderungen den Zuspruch als neue Version. Die Frage welche der beiden besser ist, ist ein weiterer der andauernden heiligen Kriege der Softwareentwicklung; versuchen Sie nicht in die Falle zu tappen, auf Ihrer Mailingliste darüber zu streiten.

Checkout

Sich eine Kopie des Projekts aus dem Projektarchiv zu beschaffen. Ein Checkout produziert meistens eine Verzeichnisstruktur, auch als Arbeitsverzeichnis (siehe unten) bekannt, von dem aus Änderungen wieder zurück ins Projektarchiv übertragen werden können. Bei manchen dezentralisierten Versionsverwaltungen ist jedes Arbeitsverzeichnis selbst ein eigenes Projektarchiv, von dem aus Änderungen an jedes Projektarchiv hoch- oder heruntergeladen werden können, das sie annehmen möchte.

Arbeitkopie[34]

Der private Verzeichnisbaum eines Entwicklers, mit dem Quellcode des Projekts und möglicherweise seine Webseite oder andere Dokumente. Eine Arbeitskopie enthält auch ein paar Metadaten, die von der Versionsverwaltung benutzt werden um zu Kennzeichen, von welchem Projektarchiv sie kommt, welche "Revision" (siehe unten) der Dateien vorliegen, usw. Im allgemeinen hat jeder Entwickler seine eigenes Arbeitskopie, indem er seine Änderungen macht, prüft und anschließend als Commit an das Projektarchiv schickt.

Revision[35]

Eine "Revision" ist für gewöhnlich eine bestimmte Version einer Datei oder einem Verzeichnis. Wenn das Projekt z.B. mit der Revision 6 der Datei D anfängt und dann jemand eine Änderung an D committed, entsteht die Revision 7 von D. Manche Systeme benutzen "Revision" auch als Bezeichnung für einen ganzen Satz an Änderungen die zusammen als Einheit committed wurden.

Diese Begriffe haben ab und zu eine Bestimmte technische Bedeutung abhängig von der Versionsverwaltung, im Allgemeinen ist die Idee jedoch immer die gleiche: Sie ermöglichen es genau über bestimmte Zeitpunkte in der Geschichte einer Datei zu reden (wie, direkt vor und nachdem ein Fehler behoben wurde). Beispielsweise: "Ja, sie hat das in Revision 10 behoben" oder "Sie hat das in Revision 10 von foo.c behoben."

Wenn man von einer Datei oder einer Sammlung von Dateien spricht ohne eine bestimmte Revision anzugeben, geht man im Allgemeinen von der aktuellsten Revision aus.

Diff[36]

Eine textuelle Representation einer Änderung. Ein Diff zeigt wie und welche Zeilen geändert wurden, sowie ein paar zusätzliche Zeilen um einen Kontext zu geben. Ein Entwickler der bereits ein wenig mit dem Code vertraut ist, kann für gewöhnlich ein Diff lesen und verstehen was die Änderung gemacht hat und sogar Fehler bemerken.

Tag[37]

Eine Beschriftung einer bestimmen Menge an Dateien ganz bestimmter Revisionen. Tags werden üblicherweise benutzt um interessante Revisionen des Projekts zu bewahren. Für jede neue veröffentlichte Version wird z.B. ein neuer "Tag" erstellt, um später genau dieselben Dateien/Revisionen aus der Versionsverwaltung herunterladen zu können. Häufige "Tag" Bezeichnungen sind Version_X_Y, Auslieferung_00456, usw.

Branch[38]

Eine Kopie des Projekts in der Versionsverwaltung, die aber vom Hauptzweig isoliert ist, damit Änderungen nicht das Übrige Projekt beeinflussen und umgekehrt, außer wenn Änderungen absichtlich von einer Seite zur Anderen portiert werden (siehe unten). Ein Branch kann man auch als Entwicklungszweig bezeichnen. Selbst wenn ein Projekt nicht explizit irgendwelche Zweige hat, gibt es dennoch einen sogenannten "Hauptzweig"[39]als den Zweig auf dem die Entwicklung stattfindet.

Zweige bieten bei der Entwicklung, die Möglichkeit verschiedene Richtungen getrennt zu verfolgen. Ein Zweig kann z.B. für experimentelle Entwicklung benutzt werden, die für den Hauptzweig nicht stabil genug wären. Umgekehrt kann ein Zweig auch als Ort benutzt werden um eine neue Version zu stabil zu bekommen. Während der Entwicklung kann die reguläre Entwicklung im Hauptzweig ohne Unterbrechung weiterlaufen; währenddessen werden auf dem Zweig der neuen Version keine Änderungen mehr zugelassen, außer sie werden von einem Versionsverwalter genehmigt. Auf diese Art, muss eine neue Version die laufende Entwicklung nicht stören. Siehe „Benutze Zweige, um Engpässe zu vermeiden“später in diesem Kapitel für eine detailliertere Erörterung über Zweige.

Merge[40]

Eine Änderung von einem Zweig in ein Anders übernehmen. Was auch portieren von Änderungen aus dem Hauptzweig in einem anderen Zweig oder umgekehrt bedeuten kann. Tatsächlich ist das sogar die häufigste Art zu mergen; man portiert selten eine Änderung zwischen zwei Zweige, die nicht beide Hauptzweige sind. Siehe „Eindeutigkeit von Informationen“ für mehr zu dieser Art zu portieren.

"Merge" hat eine zweite, verwandte Bedeutung: Die Versionsverwaltung macht einen Merge, wenn zwei Leute die gleiche Datei bearbeitet haben, sodass die Änderungen sich nicht überlappen. Da die Änderungen nicht miteinander kollidieren, werden die Änderungen in die eigenen Kopie (mit eigenen Änderungen) übertragen, bzw. die Kopie wird aktualisiert. Das kommt sehr häufig vor, besonders in Projekten bei dem mehrere Entwickler am gleichen Code arbeiten. Wenn zwei verschiedene Änderungen doch überlappen, gibt es einen "Konflikt"; siehe unten.

Konflikt

Was geschieht wenn zwei Personen gleichzeitig unterschiedliche Änderungen vornehmen, an der gleichen Stelle im Code. Jede Versionsverwaltung erkennt Konflikte automatisch, und benachrichtigt mindestens einen der Beteiligten, dass ihre Änderungen mit denen von anderen kollidieren. Der Konflikt muss dann von einem Menschen bereinigt (engl. resolve) und an die Versionsverwaltung übermittelt werden.

Lock

(de. Schloss/Sperre) Eine Möglichkeit eine exklusive Absicht auf eine Datei oder ein Verzeichnis zu erklären. z.B.: "Ich kann gerade keine Änderungen an der Webseite machen. Es scheint das Alfred alles gesperrt hat während er die Hintergrundbilder korrigiert". Nicht jede Versionsverwaltung bieten überhaupt die Möglichkeit Dateien zu sperren, und solche die es tun erfordern nicht alle, dass sie auch benutzt wird. Das liegt daran, dass parallele, gleichzeitige Entwicklung der Normalfall ist und Sperren auf Dateien, diesem Ideal (üblicherweise) widersprechen.

Eine Versionsverwaltung die einen Lock erfordert um einen Commit zu machen, benutzt das sogenannte lock-modify-unlock Verfahren. Solche die es nicht erfordern, nutzen das copy-modify-merge Verfahren. Eine ausgezeichnete tiefgehende Erklärung und Vergleich der beiden Methoden ist auf http://svnbook.red-bean.com/svnbook-1.0/ch02s02.html zu finden. Im allgemeinen ist die copy-modify-merge Methode besser für die Open-Source-Entwicklung und jede Versionsverwaltung in diesem Buch unterstützen sie.

Wahl einer Versionsverwaltung

Zum Zeitpunkt dieses Schreibens sind die beiden verbreitetsten Systeme für Versionsverwaltung in der Welt der freien Software das Concurrent Versions System oder auch CVS (http://www.cvshome.org/) und Subversion (SVN, http://subversion.tigris.org/).

CVS gibt es schon lange. Die meisten erfahrenen Entwickler sind bereits damit vertraut, es erledigt die Aufgabe mehr oder weniger gut und da es die Norm ist, werden Sie keine lange Debatten darüber führen müssen, ob es die richtige Wahl war. CVS hat jedoch einige Nachteile. Es bietet keine einfache Möglichkeit an, Änderungen über mehrere Dateien abzufragen; es erlaubt nicht, Dateien im Projektarchiv umzubenennen oder zu kopieren (was besonders nervt, wenn Sie Ihren Code neu organisieren wollen, nachdem Sie das Projekt gestartet haben); es bietet nur dürftige Merge-Unterstützung; es kann nicht sonderlich gut mit großen oder binären Dateien umgehen; und manche Vorgänge sind bei vielen Dateien sehr langsam.

Kein Fehler von CVS ist fatal und es ist immer noch ziemlich beliebt. In den vergangenen Jahren hat das neuere Subversion an Boden gewonnen, inbesondere bei neuen Projekten.[41]. Wenn Sie ein neues Projekt anfangen, empfehle ich Ihnen Subversion.

Da ich andererseits selbst an dem Subversion-Projekt arbeite, könnte man meine Objektivität berechtigt in Frage stellen. In den letzden Jahren sind ein paar neue Versionsverwaltungssysteme erschienen. Anhang A, Systeme zur Versionsverwaltung listet alle mir bekannten auf. Wie diese Liste klar macht kann die Entscheidung für eine Versionsverwaltung zu einem lebenslangen Forschungsprojekt werden. Möglicherweise wird Ihnen die Entscheidung erspart bleiben weil sie von Ihrer Hosting-Seite bereits getroffen wurde. Wenn Sie sich aber für eines entscheiden müssen, fragen Sie andere Entwickler, finden Sie heraus womit Andere bereits Erfahrung haben, suchen Sie sich eines aus und bleiben Sie dabei. Jede stabile, ausgereifte Versionsverwaltung reicht aus; Sie müssen sich keine Sorgen darüber machen, dass Sie eine furchtbar schlechte Entscheidung treffen werden. Wenn Sie sich einfach nicht entscheiden können, dann nehmen Sie CVS. Es ist immer noch die Norm und wird es auch wahrscheinlich ein paar Jahre lang bleiben. Viele andere Systeme unterstützen auch die Konvertierung in eine Richtung von einem CVS Archiv, Sie können sich also später auch umentscheiden.

Nutzung einer Versionsverwaltung

Die Empfehlungen in diesem Abschnitt sind nicht auf eine bestimmte Versionsverwaltung abgestimmt und sollten in allen Systemen einfach zu implementieren sein. Für weitere Details, schlagen Sie in der Dokumentation Ihrer Versionsverwaltung nach.

Versioniere alles

Benutzen Sie die Versionsverwaltung nicht nur für den Quellcode Ihres Projekts, sondern auch die Webseite, Dokumentation, FAQ, Entwurfsskizen und alles andere, was jemand vielleicht bearbeiten möchte. Behalten Sie alles direkt neben dem Quellcode, im selben Projektarchiv. Jede Information, die sich lohnt niederzuschreiben, ist es auch Wert im Projektarchiv zu sein – also jede Information die sich ändern könnte. Sachen die sich nicht ändern, sollten archiviert und nicht versioniert werden. Eine E-Mail ändert sich beispielsweise nicht, wenn sie einmal abgeschickt wurde; deshalb würde es keinen Sinn machen sie zu versionieren (es sei denn sie wird zu einem Teil eines größeren, sich entwickelnden Dokuments).

Der Grund warum es wichtig ist alles an einem Ort zu versionieren ist, dass Personen nur eine Methode lernen müssen um Änderungen einzureichen. Oftmals, wird ein Beteiligter damit anfangen Änderungen an der Webseite oder der Dokumentation zu machen, und gehen später dazu über kleine Beiträge am Quellcode zu machen. Wenn das Projekt dasselbe System für alle Beiträge verwendet, müssen Beteiligte nur eine Methode lernen. Alles zusammen zu versionieren, bedeutet auch, dass neue Funktionen gleich zusammen mit ihrer zugehörigen Aktualisierungen an der Doku eingereicht werden können, sodass ein Zweig für den Code auch ein Zweig für die Doku mit sich bringt, usw.

Behalten Sie keine generierte Dateien im Projektarchiv. Sie sind nicht wirklich bearbeitbare Daten, da sie aus anderen Daten erzeugt werden. Manche Build-Systeme erzeugen beispielsweise configure aus der Vorlage configure.in. Um eine Änderung an configure vorzunehmen, würde man configure.in bearbeiten und es daraus neu erzeugen lassen; weßhalb lediglich die Vorlage configure.in "bearbeitbar" ist. Versionieren Sie lediglich die Vorlage – wenn Sie die erzeugten Dateien auch versionieren, wird man zwangsläufig vergessen sie neu zu erzeugen nachdem man eine Änderung an einer Vorlagen eingespielt hat. Die daraus resultierende Inkonsistenz wird endlose Verwirrung stiften.[42]

Zu der Regel, dass alle bearbeitbare Dateien im Projektarchiv sein sollten, gibt es eine Ausnahme: den Bugtracker. Eine Bug-Datenbank enthält eine Menge bearbeitbarer Daten, kann aber aus technischen Gründen diese Daten im allgemeinen nicht im Projektarchiv speichern. (Manche Tracker haben eigene primitive Funktionen zur Versionierung, die allerdings von der Versionsverwaltung des Projekts getrennt ist.)

Zugang per Browser

Das Projektarchiv eines Projekts sollte per Browser erreichbar sein. Das bedeutet nicht nur die neuste Version der einzelnen Dateien einsehen zu können, sondern auch in der Zeit zurück zu gehen und frühere Revisionen der Dateien zu sehen, die Unterschiede zwischen den verschiedenen Versionen der Dateien sehen zu können, die commit-logs bestimmter Änderungen lesen zu können, usw.

Der Browser-Zugang ist wichtig, denn er bietet ein leichtgewichtiges Portal zu den Projekt-Daten. Ist der Zugriff per Browser nicht möglich, dann würde jemand, nur um eine bestimmte Datei zu untersuchen (sagen wir, um nachzuschauen ob ein bestimmter Bugfix es in den Code geschafft hat), zuerst lokal eine Versionsverwaltungs-Software installieren müssen, was eine einfache zweiminutige Anfrage zu einer halbstündigen Aufgabe macht.

Der Browser-Zugang erlaubt auch normale URLs auf bestimmte Revisionen von Dateien oder die jeweils aktuellste Revisionen. Das kann bei technischen Diskussionen sehr nützlich sein, oder falls man jemanden auf die Dokumentation verweisen will. Man könnte zum Beispiel anstatt "Eine ausführliche Anleitungen zum Fehlermanagement enthält die Datei community-guide/index.html deiner lokalen Arbeitskopie." folgendes schreiben: "Eine ausführliche Anleitungen zum Fehlermanagement kannst du unter http://subversion.apache.org/docs/community-guide/ nachlesen.", wobei die URL auf die aktuelle Version der Datei zeigt. Die URL ist überlegen: sie ist eindeutig und erübrigt die Frage, ob der Angesprochene wirklich eine aktuelle Arbeitskopie verwendet.

Manche Versionsverwaltungssysteme haben eine eingebaute Funktion um das Projektarchiv online zu durchsuchen, andere verlassen sich hierfür auf zusätzliche Software. Drei Beispiele hierfür sind ViewCVS (http://viewcvs.sourceforge.net/), CVSWeb (http://www.freebsd.org/projects/cvsweb.html), und WebSVN (http://websvn.tigris.org/). Ersteres funktioniert sowohl mit CVS als auch Subversion, das Zweite nur mit CVS und Letzteres nur mit Subversion.

Commit-E-Mails

Jeder Commit an das Projektarchiv sollte eine E-Mail erzeugen, die zeigt, wer den Commit gemacht hat, wann er gemacht wurde, welche Dateien und Verzeichnisse sich geändert haben und was sich an ihnen geändert hat. Die E-Mail sollte auf eine bestimmte Mailingliste gehen, eine andere als die Liste der Entwickler. Diese und andere interessierte Beteiligte sollten ermutigt werden, sich auf der Commit-Liste anzumelden, da es die effektivste Art ist sich über die Ereignisse auf Code-Ebene des Projekts auf dem Laufenden zu halten. Abgesehen von den offensichtlichen technischen Vorteilen der Überprüfung durch andere Entwickler (siehe „Code Review“), können die Commit E-Mails dazu beitragen eine Gemeinschaft aufzubauen, da sie eine gemeinsame Umgebung schaffen indem Personen auf Ereignisse (Commits) reagieren können von denen sie wissen das Andere sie auch wahrnehmen.

Wie man Commit E-Mails einrichtet, hängt von Ihrer Versionsverwaltung ab, meistens gibt es aber hierfür einen Script oder eine andere Einrichtung bei ihrer Software. Wenn Sie Schwierigkeiten bekommen es zu finden, schlagen Sie in Ihrer Dokumentation den Begriff hooks, insbesondere auch post-commit hook nach, bei CVS auch loginfo hook genannt. Diese Commit-Hooks sind eine allgemeine Möglichkeit, Befehle nach jedem Commit zu schalten. Der Hook wird von einem Commit ausgelöst, ihm werden alle Informationen über den Commit übergeben, mit denen er dann vordefinierte Aufgaben ausführen kann, wie z.B. eine E-Mail abschicken.

Bei fertig eingerichteten Systemen für Commit E-Mails werden Sie möglicherweise das übliche Verhalten ändern wollen:

  1. Manchmal beinhalten die Commit E-Mails nicht die tatsächlichen Diffs und geben stattdessen eine URL an, bei dem man die Änderungen über das Web-Portal des Projektarchivs einsehen kann. Obwohl es gut ist eine URL anzugeben, auf der man später verweisen kann, ist es auch sehr wichtig, dass die Diffs in den Nachrichten enthalten sind. E-Mails zu lesen gehört schon zum Alltag der Leute, wenn also die Änderungen gleich in der E-Mail zu lesen sind, werden Entwickler sie auf der Stelle untersuchen, ohne ihre E-Mail-Anwendung verlassen zu müssen. Wenn sie erst auf eine URL klicken müssen werden es die Meisten bleiben lassen, da es eine weitere Aktion erfordert anstatt fortzusetzen was sie bereits angefangen hatten. Desweiteren geht es bei Fragen über die Änderung viel schneller einfach auf die E-Mail zu antworten und eine Bemerkung an entsprechender Stelle zu schreiben als eine Webseite zu besuchen und mühselig den Diff aus dem Webbrowser heraus in die E-Mail zu kopieren.

    (Wenn der Diff natürlich riesig ist, wie z.B. wenn eine große Menge neuer Code im Projektarchiv eingefügt wurde, macht es natürlich Sinn den Diff wegzulassen und nur die URL anzubieten. Die meisten Systeme für Commit E-Mails können diese Art der Verkürzung automatisch. Wenn Ihres es nicht kann, ist es immer noch besser, die Diffs mitzuschicken und gelegentlich mit riesigen E-Mails zu leben, als die Diffs komplett auszuschalten. Bequeme Möglichkeiten zur Überprüfung und Bewertung sind ein Eckstein der gemeinschaftlichen Entwicklung und deshalb unerlässlich.)

  2. Der Reply-to-Header der Commit-E-Mails sollte auf die Mailingliste der Entwickler eingestellt sein, nicht auf die Commit-Liste. Wenn also jemand eine Commit-E-Mail durchgelesen und bewertet hat und daraufhin eine Antwort schreibt, sollte die Antwort an die Liste der Entwickler gehen auf dem technische Angelegenheiten üblicherweise stattfinden. Es gibt hierfür ein paar Gründe. Erstens wollen Sie alle technischen Diskussionen auf einer Liste behalten, Leute erwarten nämlich, dass sie dort gehalten werden und so auch nur ein Archiv durchsucht werden muss. Zweitens könnte es interessierte Parteien geben, die nicht bei der Commit-Liste angemeldet sind. Drittens wird die Commit-Liste als Dienst verstanden um Commits zu verfolgen und nicht um Commits zu verfolgen und gelegentlich auch technische Diskussionen zu führen. Wer sich auf den Commit-Liste angemeldet hat, will nichts anderes als Commit-E-Mails; wenn Ihnen also anderes Material über diese Liste zugesandt wird, bricht das ein ungesprochenes Übereinkommen. Viertens schreiben Beteiligte oft Programme um die Commit-E-Mails zu lesen und zu verarbeiten (z.B. um sie auf einer Webseite anzuzeigen). Diese Programme sind auf eine konsistente Formatierung ausgelegt, nicht jedoch auf inkonsistente von Menschen geschriebene E-Mails.

    Beachten Sie dass dieser Ratschlag, Reply-to umzuschreiben nicht den Empfehlungen aus „Die große "reply-to"-Debatte“ in einem früheren Abschnitt dieses Kapitels widerspricht. Es ist immer in Ordnung, wenn der Absender einer Nachricht Reply-to setzt. In diesem Fall ist der Absender die Versionsverwaltungs selber und es setzt Reply-to um anzudeuten, dass der angemessene Ort für Antworten die Entwickler-Liste ist und nicht die Commit-Liste.

Benutze Zweige, um Engpässe zu vermeiden

Laien im Umgang mit Versionsverwaltung scheuen sich manchmal vorm Verzweigen und Zusammenführen. Das ist wahrscheinlich ein Nebeneffekt des Erfolgs von CVS: Die Schnittstellen von CVS um Zweige zu machen und wieder zusammenzuführen sind nicht ganz eingängig, weshalb viele sich angeeignet haben diese Operationen komplett zu vermeiden.

Wenn Sie zu diesen Leuten gehören, nehmen Sie sich vor alle Ängste die Sie haben mögen zu besiegen und nehmen Sie sich die Zeit um zu lernen, wie man Zweige macht und wieder zusammenführt. Es sind keine schwierigen Vorgänge, wenn man sich erst einmal daran gewöhnt hat und sie werden mit der Zeit immer wichtiger, sowie ein Projekt immer mehr Entwickler aufnimmt.

Zweige sind wichtig da sie eine knappe Ressource – den Platz im Code des Projekts – im Überfluss bereitstellt. Normalerweise arbeiten alle Entwickler im gleichen Sandkasten und bauen an der gleichen Burg. Wenn jemand eine neue Zugbrücke anbauen will, jedoch nicht alle überzeugen kann, dass es eine Verbesserung wäre, ermöglicht ein Zweig mit ihr in einer eigenen isolierte Ecke zu experimentieren. Wenn es funktioniert kann sie die anderen Entwickler einladen, sich das Ergebnis anzuschauen. Wenn alle zustimmen, dass das Ergebnis gut ist können sie mittels der Versionsverwaltung die Zugbrücke aus dem Burgflügel in die Haupt-Burg übernehmen (einen "Merge" machen).

Es ist einfach zu erkennen, wie diese Fähigkeit die gemeinschaftliche Entwicklung fördert. Menschen brauchen die Freiheit Neues auszuprobieren ohne das Gefühl zu bekommen andere bei der Arbeit zu stören. Gleichermaßen gibt es Zeiten an denen es wichtig ist, bestimmten Code von der alltäglichen Entwicklung zu isolieren, um einen Fehler zu beheben oder eine neue Version stabil zu machen (siehe „Stabilisierung einer neuen Version“ und „Wartung mehrerer Versionszweige“ im Kapitel Kapitel 7, Paket-Erstellung, Veröffentlichung, und tägliche Entwicklung ) ohne sich über ein bewegliches Ziel Gedanken zu machen.

Seien Sie großzügig bei der Nutzung von Zweigen und ermutigen Sie andere, ebenso zu verfahren. Achten Sie aber auch darauf, dass jeder Zweig nur so lange aktiv bleibt wie nötig. Jeder aktive Zweig beansprucht die Aufmerksamkeit der Gemeinschaft ein klein wenig. Selbst diejenigen die nicht an einem Zweig arbeiten, behalten noch einen groben Überblick über die Ereignisse darin. Diese Aufmerksamkeit ist natürlich wünschenswert und Commit-Nachrichten sollten auch für Zweige eingeschaltet sein, genau wie für jeden anderen Commit. Zweige sollten jedoch nicht zu einer Methode werden, die Gemeinschaft zu spalten. Mit seltenen Ausnahmen sollte jeder Zweig das Ziel haben, irgendwann wieder zurück in den Hauptzweig überzugehen und zu verschwinden.

Eindeutigkeit von Informationen

Merges haben eine wichtige Konsequenz: Dieselbe Änderung sollte niemals doppelt committet werden. D.h. eine bestimmte Änderung sollte durch das Versionsverwaltungssystem nur genau einmal übernommen werden. Die Revision (oder die Gruppe von Revisionen) in dem diese Änderung eingebracht wurde, ist von da an seine eindeutige Kennung. Wenn sie auf weitere Zweige angewendet werden soll, sollte sie von ihrem ursprünglichen Eintrittspunkt aus in diese anderen Ziele portiert werden – man sollte also nicht mehrere textgleiche Änderungen committen, was zwar die gleiche Wirkung auf den Code haben würde, aber eine genaue Buchführung unmöglich machen würden.

Die praktische Auswirkung dieser Empfehlung sind unterschiedlich, je nach Versionsverwaltungssystem. Manche Systeme erfassen einen Merge als besonderes Ereignis, grundsätzlich unterschiedlich zu einem normalen Commit, mit eigenen Metadaten. Bei anderen wird das Ergebnis eines Merges genau wie jeder andere Commit übernommen, in solchen Fällen sollte man dafür sorgen, dass sich ein "Merge-Commit" im Commit-Log klar von einem "Änderungs-Commit" unterscheidet. In dem Commit-Log von einem Merge sollte nicht die Nachricht der ursprünglichen Änderung wiederholt werden. Stattdessen sollten Sie lediglich angeben, dass es sich um einen Merge handelt, und die Revisionsnummer der Ursprünglichen Änderung angeben und höchstens einen Satz, um die Auswirkungen der Änderung zusammenzufassen. Wenn jemand den kompletten Commit-Log sehen will, kann er die ursprünglichen Revisionen aufsuchen.

Es ist wichtig zu vermeiden, die Commit-Logs zu wiederholen, da Log-Nachrichten manchmal nach dem Commit geändert werden. Wenn die Log- Nachricht einer Änderung bei jedem Merge wiederholt würde, blieben selbst bei einer Korrektur der ursprünglichen Nachricht alle Kopien unverändert – was später unweigerlich zu Verwirrung führen kann.

Dasselbe Prinzip gilt beim Rückgängigmachen einer Änderung. Wenn eine Änderung wieder vom Code entfernt wird, sollte sein Commit-Log lediglich festhalten, dass die Änderung einer bestimmten Revision rückgängig gemacht wird und nicht eine Beschreibung der tatsächlichen Änderungen am Code, da diese Information aus der ursprünglichen Änderungen und sein Log ersichtlich ist. Selbstverständlich sollte der Log auch den Grund für die Entfernung nennen, jedoch nichts aus dem ursprünglichen Log wiederholen. Wenn möglich gehen Sie zurück und Ändern Sie den Log der ursprünglichen Änderung und weisen Sie darauf hin, dass sie zurückgedreht wurde.

Die vorhergehenden Passagen implizieren die Verwendenung einer konsistenten und gleichbleibende Syntax um auf Revisionen Bezug zu nehmen. Das ist nicht nur in den Logs hilfreich, sondern auch in E-Mails, dem Bugtracker und anderswo. Wenn Sie CVS verwenden, schlage ich "path/to/file/in/project/tree:REV" als Format vor, wobei REV eine CVS Revisionsnummer wie "1.76" darstellt. Wenn Sie Subversion verwenden, ist die übliche Syntax für die Revision 1729 "r1729" (Datei-Pfade sind bei Subversion nicht nötig, da es globale Revisionsnummern verwendet). Andere Systemen haben meistens ihre eigene übliche Syntax um Änderungen zu kenzeichnen. Konsistente Bezeichnungen erleichtern die Buchhaltung eines Projekts ungemein (was wir in Kapitel 6, Kommunikation und Kapitel 7, Paket-Erstellung, Veröffentlichung, und tägliche Entwicklung ) sehen werden und da ein großer Teil der Buchhaltung von Freiwilligen erledigt wird, muss es so einfach wie Möglich sein.

Siehe auch „Neue Versionen und tägliche Entwicklung“ im Kapitel Kapitel 7, Paket-Erstellung, Veröffentlichung, und tägliche Entwicklung .

Autorisierung

Die meistene Versionsverwaltungen bieten Funktionen, um bestimmten Personen Schreibzugriff auf einzelne Bereiche des Projektarchivs zu erlauben oder zu verwehren. Nach dem Grundsatz, dass jemand, sobald man ihm einen Hammer in die Hand gibt, anfangen wird, überall Nägel zu sehen, wird diese Funktion von vielen Projekten benutzt, um den Beteiligten lediglich Schreibzugriff auf Bereiche zu geben mit denen sie sich offensichtlich auskennen und so sichergestellt ist, dass sie nirgendwo sonst Schreibzugriff haben. (Siehe „Committer“ im Kapitel Kapitel 8, Leitung von Freiwilligen indem beschrieben ist, wie Projekte entscheiden wer wo Änderungen machen kann.)

Mit einer solch scharfen Kontrolle können Sie wahrscheinlich kaum Schaden anrichten, eine lockerere Haltung ist aber auch in Ordnung. Manche Projekte benutzen einfach ein Vertrauenssystem: Wenn einer Person Commit-Zugriff gewährt wird, wenn auch nur für einen Teilbereich des Projektarchivs, erhält diese in Wirklichkeit den Schlüssel, um überall im Projekt zu Änderungen vorzunehmen. Sie wird einfach darum gebeten, sich auf ihren Bereich zu beschränken. Denken Sie daran, dass hierin keine echte Gefahr besteht: In einem aktiven Projekt wird sowieso jeder Commit überprüft. Wenn jemand in einem Bereich etwas ändert, in dem er nichts zu suchen hat, werden es andere bemerken und etwas sagen. Wenn eine Änderung rückgängig gemacht werden muss, ist das auch kein Problem – es ist sowieso alles in der Versionsverwaltung, also kann man es einfach rückgängig machen.

Die Sache locker anzugehen hat mehrere Vorteile. Erstens gibt es keinen weiteren Aufwand um Entwickler zusätzliche Rechte einzuräumen, sobald sie sich auf andere Bereiche ausweiten (was meistens irgendwann passiert, wenn sie länger beim Projekt bleiben). Sobald die Entscheidung getroffen wurde, kann die Person gleich anfangen Änderungen im neuen Bereich zu machen.

Zweitens kann die Erweiterung viel feiner granuliert werden. Allgemein wird ein Commit-Berechtigter im Bereich X der auch im Bereich Y arbeiten will, anfangen Patches für Y einzureichen und darum bitten, dass sie überprüft werden. Wenn jemand der bereits Zugriff auf dem Bereich Y hat solch einen Patch sieht und ihm zustimmt, können sie dem Autor einfach sagen, dass sie die Änderung gleich selber einspielen können(natürlich mit Namensangabe vom Überprüfenden bzw, Zustimmenden im Commit-Log). Auf diese Art stammt der Commit von dem, der ihn auch geschrieben hat, was sowohl aus Sicht der Informationsverwaltung als auch der Anerkennung vorzuziehen ist.

Schließlich, und das ist vielleicht das Wichtigste, regt ein System, das auf Ehre basiert, eine Atmosphäre des Vertrauens und des gegenseitigen Respekts an. Jemandem Commit-Zugriff auf einem Teilbereich zu geben, ist eine Aussage über ihre fachliche Vorbereitung – es sagt: "Wir sehen, dass du die Kenntnisse hast, um auf einem Gebiet Änderungen zu machen, also leg los". Strikte Autorisierung aufzuerlegen, sagt aber: "Wir behaupten nicht nur, dass deine Kenntnisse begrenzt sind, wir sind auch ein wenig skeptisch im Bezug auf deine Absichten". Das ist keine Behauptung, die Sie in den Raum stellen wollen, wenn es sich vermeiden lässt. Jemanden an dem Projekt als commit-berechtigt zu beteiligen, ist eine Gelegenheit, ihn in einen Kreis vertrauter Personen aufzunehmen. Das erreicht man am besten, indem man ihm mehr Macht gibt als er letztlich braucht, und ihn darüber informiert, dass es an ihm ist, sich innerhalb der genannten Grenzen zu bewegen.

Das Subversion-Projekt arbeitet schon seit vier Jahren nach dem Ehren-Prinzip, mit 33 voll -und 43 teil-berechtigten Entwicklern zum Zeitpunkt dieses Schreibens. Der einzige Unterschied, den das System macht, ist zwischen Commit-Berechtigten und nicht Commit-Berechtigten; weitere Unterteilungen bestehen allein auf zwischenmenschlicher Ebene. Dennoch hatte man dort nie Probleme mit den Grenzen der Berechtigungen. Es gab ein oder zwei Missverständnisse über das Ausmaß der Commit-Berechtigungen, die jedoch immer schnell und freundlich gelöst wurden.

Offensichtlich muss man sich auf strikte Autorisierung verlassen können, wenn Selbstkontrolle nicht sinnvoll ist. Solche Situationen sind jedoch selten. Selbst bei Unmengen Code und hunderten oder tausenden Entwicklern, sollte ein Commit zu jedem beliebigen Modul von denen zuständigen Personen überprüft werden, die auch erkennen können ob jemand an eine Stelle etwas geändert hat die er nicht sollte. Wenn Änderungen nicht regelmäßig überprüft werden, dann hat das Projekt ohnehin größere Probleme als die Commit-Berechtigung.

Insgesamt sollte man nicht allzuviel Zeit damit verbringen, die Berechtigungen der Versionsverwaltung auszutüfteln, es sei denn Sie haben einen ganz bestimmten Grund dazu. Es wird für meistens wenig handfesten Nutzen bringen und es hat seine Vorteile sich stattdessen auf menschliche Kontrolle zu verlassen.

Natürlich sollte man nichts hiervon so auffassen, dass die Beschränkungen an und für sich unwichtig sind. Es wäre schlecht für das Projekt, Teilnehmer anzuregen Bereiche zu ändern, für die sie nicht qualifiziert sind. Desweiteren geben viele Projekte dem vollen (uneingeschränkten) Zugriff auf das Projektarchiv einen besonderen Status: Es impliziert, dass der Teilnehmer das Recht hat, über Fragen die das ganze Projekt betreffen abzustimmen. Dieser politische Aspekt der Commit-Berechtigung wird weiter in „Wahlberechtigung“ im Kapitel Kapitel 4, Soziale und politische Infrastruktur behandelt.



[33] im Deutschen auch manchmal "Versionskontrolle" genannt.

[34] engl. "working copy"

[35] im engl. auch change oder changeset (de. Satz von Änderungen)

[36] kurz für difference(de. Unterschied)

[37] de. Etikett

[38] de. Zweig/Ast

[39] engl. "main branch" auch "main line" oder "trunk" de. "Stamm"

[40] im engl. auch "port" de. Zusammenführung/Portierung

[42] Eine andere Meinung im Bezug auf die Versionierung von configure Dateien, kann man in "configure.in and version control" bei http://versioncontrolblog.com/2007/01/08/configurein-and-version-control/ von Alexey Makhotkin nachlesen.