Das Arbeiten mit Sperren

In Kapitel 3 wurde beschrieben, dass bei dem Einsatz von Subversion alle Veränderungen an Dateien immer nur auf Kopien, den lokalen Arbeitskopien, vorgenommen werden. Gleichzeitige Änderungen in verschiedenen Arbeitskopien werden von Subversion weitgehend automatisch zusammengeführt. Diese Arbeitsweise, die Subversion von seinem Vorgänger CVS übernommen hat, hat sich - zählt man die mit CVS gemachten Erfahrungen hinzu - in jahrzehntelanger Praxis bewährt. Allerdings setzt diese Arbeitsweise Dateien voraus, die sich automatisch zusammen führen lassen. Bei den von Programmierern verwendeten Sourcecodedateien ist das fast immer der Fall. Im Zeitalter von Multimedia und Internet möchte man jedoch auch Bilddateien und andere Medien unter die Versionsverwaltung stellen. Solche Dateien lassen sich nicht automatisch zusammenführen, daher funktioniert der normale Arbeitszyklus von Subversion mit solchen Dateien nicht. Natürlich kann man Bilddateien und andere binäre Medien in ein Subversion-Repository einchecken. Ändern jedoch zwei Personen gleichzeitig eine solche Datei, so kann Subversion die Änderungen der beiden Personen nicht zusammenführen. Wer als letztes eincheckt, wird zum Update gezwungen. Subversion verweigert dann das Einchecken, weil die im Repository vorhandene Version neuer ist als die eigene. Das so erzwungene Update führt unweigerlich zu einem Konflikt, da sich die Bilddateien nicht zusammenführen lassen.

Weil sich binäre Dateien nicht automatisch zusammenführen lassen, muss man den Arbeitsablauf für solche Dateien ändern, möchte man einen reibungslosen Ablauf im Team gewährleisten. Da eine gleichzeitige Bearbeitung der Dateien nicht möglich ist, muss dafür gesorgt werden, dass eine Datei nur von einem Teammitglied zur Zeit bearbeitet werden kann. Änderungen verschiedener Teammitglieder an der gleichen Datei müssen nacheinander erfolgen. Der Zugriff auf die Datei muss serialisiert werden. Das Versionsmanagementsystem muss sicherstellen, dass nur ein Teammitglied zur Zeit Zugriff auf eine binäre Datei erhält. Subversion hat zu diesem Zweck mit der Version 1.2 das Konzept des Sperrens von Dateien eingeführt.

Das mit Subversion 1.2 eingeführte Konzept des Sperrens von Dateien funktioniert nur mit einzelnen Dateien. Das Sperren von Verzeichnissen ist bisher nicht möglich!

Subversion kann Dateien sperren, um sie vor dem gleichzeitigen Zugriff mehrere Benutzer zu schützen. Solche Sperren werden im Kontext von Subversion als Locks oder Sperren bezeichnet. Fordert man eine Sperre für eine Datei an, so bekommt man das exklusive Bearbeitungsrecht für diese Datei:

svn lock michel.jpg

Subversion gibt aus:

'michel.jpg' gesperrt durch 'elke'.

Die Datei ist für alle anderen Benutzer außer Elke gesperrt. Elke kann nun die Datei bearbeiten und checkt ihre Änderungen ganz normal ein, wenn sie mit der Bearbeitung fertig ist:

svn commit -m "Bild aufgehellt" michel.jpg

Subversion gibt aus:

Sende          michel.jpg
Übertrage Daten .
Revision 42 übertragen.

Die Ausführung des Befehls commit überführt Elkes Änderungen in das Repository. Außerdem wird dadurch die Sperre auf der Datei michel.jpg automatisch aufgehoben. Der Hintergrund dieses Verhaltens von Subversion ist die Annahme, dass mit der Überführung der Änderungen in das Repository die Bearbeitung der Datei beendet ist und somit auch die Sperre nicht mehr benötigt wird.

Subversion hebt bei der Ausführung des Befehls commit nicht nur Sperren auf tatsächlich eingecheckten Dateien auf, sondern auch auf nicht veränderten und damit nicht eingecheckten Dateien. Wendet man den Befehl commit auf ein Verzeichnis an, so werden alle Sperren in diesem Verzeichnis und in eventuell vorhandenen Unterverzeichnissen aufgehoben. Diese Arbeitsweise von Subversion soll sicherstellen, dass Dateien nicht unnötig lange gesperrt werden und dass Sperren nicht vergessen werden. Sollen Sperren über das Einchecken hinaus bestehen bleiben, so ruft man den Befehl commit mit der Option --no-unlock auf.

Natürlich kann es auch sein, dass Elke die Bearbeitung der Datei michel.jpg doch nicht durchführen möchte und die Sperre daher sinnvollerweise aufhebt. Dazu ruft Elke den Befehl unlock auf:

svn unlock michel.jpg

Subversion gibt aus:

'michel.jpg' freigegeben.

Die interessante Frage ist jedoch, was passiert wenn ein anderer Benutzer versucht, Änderungen an der Datei vorzunehmen und einzuchecken? Dazu sei ein weiterer Benutzer, Erik, betrachtet. Erik besitzt bereits eine lokale Arbeitskopie, in der die Datei michel.jpg schon vorhanden ist. Erik bearbeitet nun diese Datei ebenfalls und möchte die Änderungen einchecken. Die von Elke gesetzte Sperre ist ihm nicht bekannt:

svn commit -m "freigestellt" michel.jpg

Subversion gibt aus:

Sende          michel.jpg
Übertrage Daten .svn: Übertragen fehlgeschlagen (Details folgen):
svn: Cannot verify lock on path '/bilder/michel.jpg';
   no matching lock-token available

Die etwas umständlich formulierte Fehlermeldung besagt, dass das Einchecken fehlgeschlagen ist, weil die Datei in einer anderen lokalen Arbeitskopie gesperrt worden ist. Da Elke die Datei michel.jpg gesperrt hat, kann Erik seine Änderungen nicht einchecken.

Subversion erzwingt, dass nur derjenige einchecken kann, der eine gesperrte Datei selbst aus der eigenen lokalen Arbeitskopie gesperrt hat. Alle anderen dürfen die gesperrte Datei nicht einchecken, sie werden von Subversion abgewiesen! Dieses Verhalten wird im Englischen als Lock Enforcement bezeichnet.

Dass Erik nicht einchecken kann, ist für ihn nicht sehr hilfreich. Er kann seine Änderungen nun verwerfen, da sie sich nicht mit den Änderungen von Elke zusammenführen lassen. Folglich reicht es bei der Arbeit mit Sperren nicht diese einfach zu setzen. Vielmehr sollten alle Benutzer wissen:

Mit diesem Wissen hätte Erik selbst zunächst versucht, eine Sperre für die Datei michel.jpg anzufordern:

svn lock michel.jpg

Subversion gibt aus:

svn: Path '/bilder/michel.jpg' is already locked by user 'elke'
   in filesystem '/var/lib/svn/db'

Anhand der Fehlermeldung hätte Erik dann festgestellt, dass die Datei michel.jpg bereits von Elke gesperrt worden ist und hätte deshalb die Datei nicht selbst bearbeitet. Natürlich muss Erik eine Datei nicht selbst sperren, um herauszufinden, ob eine Sperre auf der Datei vorhanden ist. Die Befehle status und info zeigen an, ob eine Datei gesperrt ist. Der Befehl status muss mit der Option -u (oder --show-updates) aufgerufen werden, damit Informationen über Sperren angezeigt werden:

svn status -u

Subversion gibt aus:

     O         45   michel.jpg
Status bezogen auf Revision:     45

Der Buchstabencode „O“ in der sechsten Spalte bedeutet, dass die Datei michel.jpg mit einer Sperre („O“ther) in einer anderen lokalen Arbeitskopie belegt ist. Um den Zustand von Sperren zu kennzeichnen, verwendet Subversion vier Buchstabencodes. Die nachfolgende Tabelle zeigt die Codes mit ihrer Bedeutung:

CodeBedeutung
KDie Datei ist in der eignen lokalen Arbeitskopie gesperrt (loc“K“ed).
ODie Datei ist in einer anderen lokalen Arbeitskopie gesperrt („O“ther).
BDie Sperre der Datei wurde gebrochen („B“roken).
TDie Sperre der Datei wurde gestohlen (s“T“ohlen).

Möchte man auch erfahren, wer die Sperre gesetzt hat, so hilft der Befehl info weiter. Informationen zu nicht selbst gesetzten Sperren werden allerdings nur angezeigt, wenn man den Befehl mit der URL der Datei im Repository aufruft:

svn info svn://zappa/var/lib/svn/bilder/michel.jpg

Subversion gibt aus:

Pfad: michel.jpg
Name: michel.jpg
URL: svn://zappa/var/lib/svn/bilder/michel.jpg
Basis des Projektarchivs: svn://zappa/var/lib/svn
UUID des Projektarchivs: 067708f7-93e4-0310-89fd-
   bd2925b0e15b
Revision: 45
Knotentyp: Datei
Letzter Autor: inge
Letzte geänderte Rev: 45
Letztes Änderungsdatum: 2005-08-14 15:10:08 +0200 (So,
   14 Aug 2005)
Sperrmarke: opaquelocktoken:aa547c8f-4bfe-0310-a377-
   cb62b19c24b6
Sperreigner: elke
Sperre erzeugt: 2005-08-14 15:16:53 +0200 (So, 14 Aug
   2005)

Die letzen drei Einträge betreffen die auf der Datei gesetzte Sperre. Sie zeigen das zur Sperre gehörende Lock Token (siehe unten, „Die Implementierung von Sperren“), wem die Sperre gehört und wann die Sperre gesetzt worden ist.

Obwohl Erik weiß, dass er per Konvention bei bestimmten Dateientypen eine Sperre setzen muss, kann er dies natürlich vergessen. Daher bietet Subversion ein weiteres Hilfsmittel an, dass an das Sperren binärer Dateien erinnern soll: die Property svn:needs-lock. Wird diese Property für eine Datei angelegt, so setzt der Subversion-Client das Dateiattribut „readonly“ (bzw. entzieht der Datei das Schreibrecht), solange die Datei nicht gesperrt ist. Der Wert der Property ist nicht entscheidend, es wird nur ausgewertet ob die Property vorhanden ist:

svn propset svn:needs-lock x michel.jpg

Subversion gibt aus:

Eigenschaft 'svn:needs-lock' für 'michel.jpg' gesetzt

Der Subversion-Client setzt das „readonly“-Attribut allerdings erst mit dem nachfolgenden Commit:

erik@zappa:~/bilder$ ls -l
total 4
-rw-r--r--  1 erik src 2518 Aug 20 08:03 michel.jpg

erik@zappa:~/bilder$ svn commit -m "Property
   svn:needs-lock gesetzt" michel.jpg
Sende          michel.jpg

Revision 50 übertragen.

erik@zappa:~/bilder$ ls -l
total 4
-r--r--r--  1 erik src 2518 Aug 20 08:03 michel.jpg

Das „readonly“-Attribut (bzw. das Fehlen des Schreibrechts auf Unix-Systemen) wird nun mit dem nächsten Update in der jeweiligen lokalen Arbeitskopie gesetzt.

Um das Setzen der Property svn:needs-lock zu automatisieren, kann man sie in der lokalen config-Datei eintragen (vergleiche Abschnitt 7.10.8, „Automatisches Setzen von Properties“). Dort trägt man bei-spielsweise folgende Zeile ein:

*.jpg = svn:mime-type=image/jpeg;svn:needs-lock=x

Der Wert, den man für die Property setzt, ist egal. Man kann hier ein beliebiges Zeichen oder eine Zeichenfolge setzen.

Das Arbeiten mit Sperren

Sperrkommentare

Analog zu den Log Messages, die beim Einchecken von Dateien und Verzeichnissen vergeben werden, lassen sich bei Sperren Sperrkommen-tare vergeben, die die gesetzte Sperre beschreiben. Im Gegensatz zu den Log Messages sind diese allerdings optional. Ein Beispiel:

svn lock -m "Sperre zum Freistellen" michel.jpg

Subversion gibt aus:

'michel.jpg' gesperrt durch 'elke'.

Der Aufruf des Befehls info auf dieser Datei gibt nun auch den Kommentar zu der Sperre aus:

svn info svn://zappa/var/lib/svn/bilder/michel.jpg

Subversion gibt aus:

[...]
Sperrmarke: opaquelocktoken:c902f9b1-1200-0410-aea4-ab5700773468
Sperreigner: elke
Sperre erzeugt: 2005-09-06 06:16:42 +0200 (Di, 06 Sep 2005)
Sperrkommentar (1 Zeile):
Sperre zum Freistellen

Der Einsatz von Sperrkommentaren dient zur Kommunikation im Team. Wenn die anderen Teammitglieder wissen, weshalb eine Datei gesperrt ist, dann werden sie eher davon absehen eine längerfristig gesperrte Datei eventuell gewaltsam an sich zu reißen, wie es im Folgenden beschrieben wird.

Das Arbeiten mit Sperren

Sperren brechen und stehlen

Die Entwickler von Subversion betrachten Sperren letztlich als ein Kommunikationsmittel und nicht als eine unüberwindbare Hürde zur Absicherung des Zugriffs auf Dateien. Dazu sei folgender Fall betrachtet: Elke sperrt die Datei michel.jpg zur Bearbeitung. Allerdings bearbeitet sie die Datei nun doch nicht mehr am selben Tag: sie geht nach Hause und möchte die Bearbeitung am nächsten Tag vornehmen. Die Datei bleibt gesperrt. Am nächsten Tag fühlt sich Elke nicht wohl und sie meldet sich krank. Die Bearbeitung soll nun durch ihren Kollegen Erik durchgeführt werden. Erik sieht sich nun mit dem Problem konfrontiert, dass er eine Datei bearbeiten möchte, die in der Arbeitskopie von Elke gesperrt worden ist. Wäre die Sperre unüberwindbar, so hätte Erik nun ein echtes Problem. Subversion sieht Sperren jedoch nicht als heilig an. Erik kann die Sperre von Elke brechen oder er kann sie stehlen.

Zum Brechen einer Sperre wird der Befehl unlock verwendet. Eine Sperre zu brechen bedeutet eine Sperre aufzuheben, die man nicht selbst aus der eigenen lokalen Arbeitskopie angelegt hat. Ein einfacher Aufruf des Befehls unlock reicht nicht aus, da die Sperre nicht aus der eigenen lokalen Arbeitskopie angelegt worden ist. Der Aufruf führt zu einer Fehlermeldung:

svn unlock michel.jpg

Subversion gibt aus:

svn: 'michel.jpg' ist in dieser Arbeitskopie nicht gesperrt

Um die Sperre zu brechen muss zusätzlich die Option --force angegeben werden. Schließlich soll nicht jeder eine Sperre einfach aufheben können. Die Angabe von --force macht deutlich, dass man eine Sperre bricht und dass dies nicht das normale Verfahren ist, eine Sperre aufzuheben.

svn unlock --force michel.jpg

Subversion gibt aus:

'michel.jpg' freigegeben.

Auch der Administrator kann Sperren brechen, er verwendet dazu das Programm svnadmin mit dem Befehl rmlocks:

svnadmin rmlocks /var/lib/svn /bilder/michel.jpg

Subversion gibt aus:

Sperre für '/bilder/michel.jpg' entfernt.

Möchte man eine Sperre entfernen, um die entsperrte Datei gleich wieder in der eigenen lokalen Arbeitskopie zu sperren, so kann man dies auch in einem Schritt tun. Man spricht in diesem Fall davon, dass man eine Sperre stiehlt. Dies geschieht durch den Aufruf des Befehls lock unter Angabe der Option --force:

svn lock --force michel.jpg

Subversion gibt aus:

'michel.jpg' gesperrt durch 'erik'

Obwohl die Datei ursprünglich von Elke gesperrt worden war, gehört die Sperre nun Erik. Erik hat die Sperre von Elke gestohlen. Dies wird deutlich, wenn Elke den Befehl status mit der Option --show-updates in ihrer lokalen Arbeitskopie aufruft:

svn status --show-updates

Subversion gibt aus:

     T         51   michel.jpg
Status bezogen auf Revision:     51

Das „T“ zeigt an, dass die Sperre gestohlen worden ist. Für Elke bedeutet dies, dass ihre Version der Datei nun nicht mehr gesperrt ist. Sie kann die jetzt von Erik gesperrte Datei folglich nicht mehr einchecken.

Eine Sperre zu stehlen hat gegenüber dem Brechen einer Sperre mit anschließendem erneuten Sperren der Datei den Vorteil, dass in der Zwischenzeit niemand anderes die Datei sperren kann. Das Entziehen der Sperre und erneute Sperren der Datei läuft dabei als eine Operation ab.

Da jedes Teammitglied Sperren brechen und stehlen kann, sind Sperren kein wirklicher Schutz vor der Veränderung durch andere. Sie sind vielmehr ein Kommunikationsmittel, das anzeigt, wer zu einem Zeitpunkt eine Datei exklusiv bearbeiten möchte. Kommt es in einem Team zum häufigen Brechen und Stehlen von Sperren, so deutet dies auf mangelnde Kommunikation im Team hin. Sperren können und sollen keine Abschottung gegen andere Entwickler bieten. Eine vollständige Abschottung durch unüberwindbare Sperren würde letztlich dem offenen Entwicklungsmodell von Subversion widersprechen.

Das Arbeiten mit Sperren

Die Implementierung von Sperren

Interessant für den Benutzer ist die Implementierung von Sperren in Subversion, da diese teilweise sichtbar wird. Identifiziert wird eine Sperre durch eine so genannte Sperrmarke oder Lock Token. Diese Sperrmarke identifiziert die Sperre eindeutig. Es wird in einer separaten Tabelle im Repository gespeichert. Es besteht aus einer längeren Reihe von Buchstaben und Ziffern. Ein Beispiel:

opaquelocktoken:6bc4725c-21ff-0310-97a9-d1c201719c9a

Diese Sperrmarke wird nicht nur im Repository gespeichert, sondern auch in der lokalen Arbeitskopie, in der die Datei gesperrt worden ist. Die Sperrmarke wird vom Befehl info ausgegeben. Ruft man den Befehl info mit einer URL als Parameter auf, so wird die Sperrmarke bei jeder gesperrten Datei ausgegeben, ruft man info dagegen aus einer lokalen Arbeitskopie auf, so wird die Sperrmarke nur angezeigt, wenn die Datei tatsächlich aus genau dieser lokalen Arbeitskopie gesperrt worden ist. Ein Beispiel, der Befehl info wird von Elke in der lokalen Arbeitskopie eingegeben, in der sie die Datei michel.jpg gesperrt hat:

svn info michel.jpg

Subversion gibt aus:

[...]
Sperrmarke: opaquelocktoken:1497d322-9aff-0310-8521-d34e458a5fa0
Sperreigner: elke
Sperre erzeugt: 2005-08-31 06:26:44 +0200 (Mi, 31 Aug 2005)

Eine Sperrmarke ist ein eindeutiges Merkmal, mit dem eine Sperre identifiziert und autorisiert wird. Da Subversion es erlaubt, Sperren zu brechen und zu stehlen, gibt es keine Notwendigkeit, die Sperrmarke geheim zu halten. Subversion betrachtet Sperren lediglich als Kommunikationsmittel, um Zugriffe auf Dateien nacheinander ablaufen zu lassen.

Kommentare und Anmerkungen zu diesem Artikel senden Sie bitte an autor@subversionbuch.de