Änderungslisten

Für einen Entwickler ist es üblich, zu einem gegebenen Zeitpunkt an mehreren unterschiedlichen, individuellen Änderungen an Teilen des Source-Codes zu arbeiten. Das liegt nicht notwendigerweise an schlechter Planung oder einer Art digitalen Masochismus. Ein Software-Engineer entdeckt oft Fehler am Rande während er an einem Teil des Codes in der Nähe arbeitet. Vielleicht ist er auch halbwegs mit einer großen Änderung fertig, wenn er feststellt, dass die von ihm übergebene Lösung besser als eine Sammlung kleinerer logischer Einheiten übergeben werden sollte. Oft befinden sich diese logischen Einheiten nicht in einem Modul, das sicher von anderen Änderungen getrennt ist. Die Einheiten könnten sich überlappen, mehrere unterschiedliche Dateien im gleichen Modul betreffen oder sogar verschiedene Zeilen in der selben Datei.

Entwickler können verschiedene Arbeitsweisen anwenden, um diese logischen Änderungen zu organisieren. Manche verwenden getrennte Arbeitskopien des selben Projektarchivs, um jede einzelne Änderung voranzutreiben. Andere wiederum wählen kurzlebige Arbeitszweige im Projektarchiv und verwenden eine einzelne Arbeitskopie, die ständig zwischen solchen Zweigen hin- und her geschaltet wird. Eine weitere Gruppe verwendet diff- und patch-Werkzeuge, um noch nicht übergebene Änderungen in entsprechenden Patch-Dateien zu sichern und wiederherzustellen Jede dieser Methoden hat ihre Vor- und Nachteile, und zu einem großen Teil beeinflussen die Details der vorzunehmenden Änderungen die Methodik, sie auseinander zu halten.

Subversion 1.5 bringt als neues Leistungsmerkmal Änderungslisten mit, die dieser Mischung eine weitere Methode hinzufügen. Im Grunde sind Änderungslisten beliebige Label (momentan höchstens eins pro Datei), die ausschließlich zum Zweck der Zusammenfassung mehrerer Dateien auf Dateien der Arbeitskopie vergeben werden. Benutzer vieler Software-Angebote von Google kennen dieses Konzept bereits. Gmail beispielsweise verfügt nicht über den traditionellen, ordnerbasierten Ansatz der Gliederung von E-Mail. In Gmail vergeben Sie beliebige Labels auf E-Mails, und mehrere E-Mails gelten zu einer Gruppe gehörend, falls sie gemeinsam ein bestimmtes Label haben. Das Ansehen nur einer Gruppe ähnlich gelabelter E-Mails wird damit zu einem einfachen Trick der Benutzeroberfläche. Viele andere Web-2.0-Präsenzen verfügen über ähnliche Mechanismen – betrachten Sie etwa die Tags, die von YouTube und Flickr verwendet werden, Kategorien, die auf Blog Posts angewendet werden, usw. Den Menschen ist heutzutage bewusst, dass die Organisation von Daten kritisch ist, die Art und Weise der Organisation jedoch ein flexibles Konzept sein muss. Das alte Paradigma der Dateien und Ordner ist für manche Anwendung zu starr.

Subversions Unterstützung von Änderungslisten erlaubt Ihnen die Erstellung von Änderungslisten durch das Anbringen von Labels auf Dateien, die Sie mit dieser Änderungsliste in Verbindung bringen wollen, das Entfernen dieser Label und die Einschränkung des Wirkbereiches von Unterbefehlen auf die Dateien mit einem bestimmten Label. In diesem Abschnitt werden wir einen detaillierten Blick darauf werfen, wie so etwas gemacht werden kann.

Erstellen und Bearbeiten von Änderungslisten

Sie können Änderungslisten mit dem Befehl svn changelist erstellen, bearbeiten und löschen. Genauer gesagt verwenden Sie diesen Befehl, um die Verbindung einer Änderungsliste mit einer Datei der Arbeitskopie herzustellen oder aufzulösen. Eine Änderungsliste wird tatsächlich erstmals dann erstellt, wenn Sie eine Datei mit diesem Änderungslisten-Label versehen; sie wird gelöscht, wenn dieses Label von der letzten damit versehenen Datei entfernt wird. Sehen wir uns einmal einen Anwendungsfall an, der diese Konzepte vorstellt.

Harry beseitigt einige Fehler in der mathematischen Logik der Rechneranwendung. Seine Arbeit veranlasst ihn, einige Dateien zu ändern:

$ svn status
M      integer.c
M      mathops.c
$

Während er die Fehlerbehebung testet, bemerkt Harry, dass seine Änderungen einen tangential in Bezug stehenden Fehler der Logik der Benutzerschnittstelle in button.c ans Tageslicht bringen. Harry entschließt sich, auch diesen Fehler als eine von seinen Mathe-Reparaturen getrennte Übergabe zu beheben. In einer kleinen Arbeitskopie mit nur einer handvoll Dateien und wenigen logischen Änderungen kann Harry wahrscheinlich seine zwei logisch gruppierten Änderungen ohne Problem im Kopf auseinander halten. Heute jedoch wird er, um den Autoren diesen Buchs einen Gefallen zu tun, die Änderungslisten von Subversion verwenden.

Harry erstellt zunächst eine Änderungsliste und stellt sie in Beziehung zu den beiden von ihm bereits geänderten Dateien. Er macht das, indem er diesen Dateien mit dem Befehl svn changelist die selbe, frei wählbare Änderungsliste zuweist:

$ svn changelist math-fixes integer.c mathops.c
Pfad »integer.c« ist nun ein Element der Änderungsliste »math-fixes«.
Pfad »mathops.c« ist nun ein Element der Änderungsliste »math-fixes«.
$ svn status

--- Änderungsliste »math-fixes«:
M      integer.c
M      mathops.c
$

Wie Sie sehen können, spiegelt die Ausgabe von svn status diese neue Gruppierung wider.

Harry legt nun los, das sekundäre Problem der Benutzerschnittstelle zu beheben. Da er weiß, welche Datei er ändern wird, weist er auch diesen Pfad einer Änderungsliste zu. Unglücklicherweise weist Harry diese dritte Datei achtlos derselben Änderungsliste wie den beiden vorigen Dateien zu:

$ svn changelist math-fixes button.c
Pfad »button.c« ist nun ein Element der Änderungsliste
»math-fixes«.
$ svn status

--- Änderungsliste »math-fixes«:
       button.c
M      integer.c
M      mathops.c
$

Zum Glück entdeckt Harry seinen Fehler. An dieser Stelle hat er zwei Optionen. Er kann die Verbindung zur Änderungsliste von button.c lösen und dann einen unterschiedlichen Listennamen zuweisen:

$ svn changelist --remove button.c
Pfad »button.c« ist nicht länger ein Element einer Änderungsliste.
$ svn changelist ui-fix button.c
msgstr "Pfad »button.c« ist nun ein Element der Änderungsliste »ui-fix«.
$

Oder er kann sich das Entfernen sparen und bloß einen neuen Änderungslisten-Namen zuweisen. In diesem Fall wird Subversion Harry warnen, dass button.c von der ersten Änderungsliste entfernt wird:

$ svn changelist ui-fix button.c
svn: warnung: Entferne »button.c« aus Änderungsliste »math-fixes«.
Pfad »button.c« ist nun ein Element der Änderungsliste »ui-fix«.
$ svn status

--- Änderungsliste »ui-fix«:
       button.c

--- Änderungsliste »math-fixes«:
M      integer.c
M      mathops.c
$

Harry hat nun zwei unterschiedliche Änderungslisten in seiner Arbeitskopie, und svn status gruppiert seine Ausgaben nach den Bezeichnungen dieser Änderungslisten. Beachten Sie, dass Harry die Datei button.c zwar noch nicht geändert hat, sie aber trotzdem als interessant in der Ausgabe von svn status erscheint, da eine Verknüpfung mit einer Änderungsliste besteht. Änderungslisten können jederzeit Dateien hinzugefügt oder entzogen werden, egal, ob sie lokale Änderungen beinhalten.

Harry behebt nun das Problem der Benutzerschnittstelle in button.c.

$ svn status

--- Änderungsliste »ui-fix«:
M      button.c

--- Änderungsliste »math-fixes«:
M      integer.c
M      mathops.c
$

Änderungslisten als Befehlsfilter

Die visuelle Gruppierung, die Harry in der Ausgabe von svn status im vorangegangenenen Abschnitt sieht, ist ganz nett, jedoch nicht so richtig nützlich. Der Befehl status ist nur einer von mehreren, die er vielleicht in seiner Arbeitskopie ausführen möchte. Erfreulicherweise können viele andere Befehle von Subversion auf Änderungslisten arbeiten, wenn die Option --changelist verwendet wird.

Wenn ihnen die Option --changelist mitgegeben wird, beschränken Befehle von Subversion ihren Wirkbereich auf die Dateien, die mit einer bestimmten Änderungsliste verknüpft sind. Falls Harry nun die eigentlichen Änderungen sehen möchte, die er an Dateien in seiner Änderungsliste math-fixes vorgenommen hat, könnte er in der Kommandozeile des Befehls svn diff ausdrücklich nur die Dateien angeben, die diese Änderungsliste ausmachen.

$ svn diff integer.c mathops.c
Index: integer.c
===================================================================
--- integer.c	(revision 1157)
+++ integer.c	(working copy)
…
Index: mathops.c
===================================================================
--- mathops.c	(revision 1157)
+++ mathops.c	(working copy)
…
$

Bei ein paar Dateien funktioniert das einwandfrei, was wäre aber, wenn Harrys Änderung 20 oder 30 Dateien beträfe? Das wäre eine schrecklich lange Liste ausdrücklich aufgeführter Dateinamen. Da Harry nun jedoch Änderungslisten verwendet, kann er das explizite Aufführen der Dateimenge in seiner Änderungsliste von nun an vermeiden und stattdessen nur den Namen der Änderungsliste angeben:

$ svn diff --changelist math-fixes
Index: integer.c
===================================================================
--- integer.c	(revision 1157)
+++ integer.c	(working copy)
…
Index: mathops.c
===================================================================
--- mathops.c	(revision 1157)
+++ mathops.c	(working copy)
…
$

Und wenn es an der Zeit ist, zu übertragen, kann Harry wieder die Option --changelist verwenden, um die Übertragung auf die Dateien einer bestimmten Änderungsliste zu beschränken. Er könnte seine Fehlerbehebung an der Benutzerschnittstelle etwa so übertragen:

$ svn ci -m "Fix a UI bug found while working on math logic." \
      --changelist ui-fix
Sende          button.c
Übertrage Daten .
Revision 1158 übertragen.
$

Der Befehl svn commit verfügt über eine zweite Option in Zusammenhang mit Änderungslisten: --keep-changelists. Normalerweise werden Verknüpfungen zu Änderungslisten nach der Übertragung von Dateien aufgelöst. Wenn jedoch --keep-changelists angegeben wird, bewahrt Subversion die Verknüpfung der übertragenen (und nun unveränderten) Dateien zur Änderungsliste. In allen Fällen berührt die Übertragung von Dateien einer Änderungsliste alle anderen Änderungslisten nicht.

$ svn status

--- Änderungsliste »math-fixes«:
M      integer.c
M      mathops.c
$
[Anmerkung] Anmerkung

Die Option --changelist wirkt lediglich als ein Filter für die Objekte eines Subversion-Befehls und fügt keine neuen Objekte hinzu. Beispielsweise ist bei einem Übertragungsbefehl, der als svn commit /path/to/dir gegeben wird, das Objekt das Verzeichnis /path/to/dir und seine Kinder (unendlich tief). Wenn Sie diesem Befehl dann die Angabe einer Änderungsliste hinzufügen, werden nur die Dateien in und unterhalb von /path/to/dir als zu übertragene Objekte betrachtet, die mit dieser Änderungsliste verknüpft sind – die Übertragung wird keine Dateien von anderen Stellen (etwa /path/to/another-dir) umfassen, egal, ob sie mit der Änderungsliste verknüpft sind, auch wenn sie zur selben Arbeitskopie gehören wie die Objekte des Befehls.

Auch der Befehl svn changelist versteht die Option --changelist. Er ermöglicht Ihnen das schnelle Umbenennen oder Entfernen einer Änderungsliste:

$ svn changelist math-bugs --changelist math-fixes --depth infinity .
svn: warnung: Entferne »integer.c« aus Änderungsliste »math-fixes«.
Pfad »integer.c« ist nun ein Element der Änderungsliste »math-bugs«.
svn: warnung: Entferne »mathops.c« aus Änderungsliste »math-fixes«.
Pfad »mathops.c« ist nun ein Element der Änderungsliste »math-bugs«.
$ svn changelist --remove --changelist math-bugs --depth infinity .
Pfad »integer.c« ist nicht länger ein Element einer Änderungsliste
Pfad »mathops.c« ist nicht länger ein Element einer Änderungsliste
$

Schließlich können sie die Option --changelist mehrfach für einen Befehl auf einer einzelnen Kommandozeile angeben. Das beschränkt den auszuführenden Befehl auf Dateien, die in irgendeiner der angegebenen Änderungslisten zu finden sind.

Einschränkungen von Änderungslisten

Die Änderungslisten von Subversion sind ein praktisches Werkzeug, um Dateien in Arbeitskopien zu gruppieren; allerdings besitzen sie ein paar Einschränkungen. Änderungslisten sind Artefakte einer bestimmten Arbeitskopie, was bedeutet, dass Änderungslisten-Zuweisungen nicht an das Projektarchiv weitergegeben und auch anderweitig nicht gemeinsam von anderen Benutzern verwendet werden können. Änderungslisten lassen sich nur Dateien zuordnen – momentan unterstützt Subversion nicht die Verwendung von Änderungslisten für Verzeichnisse. Schließlich können Sie einer gegebenen Datei der Arbeitskopie höchstens eine Änderungsliste zuweisen. Hier passen die Analogien der Blog-Posts-Kategorien oder der Foto-Tags nicht mehr – sollte es notwendig sein, eine Datei mehreren Änderungslisten zuzuweisen, haben Sie Pech.