//

SVN Regel: Commite nicht auf einem Tag – es sei denn, es ist keiner!

2.3.2009 | 3 Minuten Lesezeit

Eine typische Situation: Nach einem langen Arbeitstag möchte man seine Arbeit in ein Subversion Repository einchecken, bekommt aber diese Meldung angezeigt:

Huch! Eigentlich wurden nur die richtigen Dateien verändert und auch die Subversion Meta Dateien sind nicht durcheinander.

Aber keine Panik, sehr wahrscheinlich spielt hier nur das Subversive Plug-in von eclipse verrückt. Vor kurzem haben wir die Entwicklungsumgebung für einen Kunden auf das aktuelle Ganymede Release von eclipse inkl. Subversive Plug-in ohne Probleme umgestellt. Die einzige Auffälligkeit war diese Meldung.

Wir haben uns die Sache dann etwas genauer angesehen und festgestellt, dass die Methode, welche prüft ob man auf einem Tag arbeitet, nicht so klug ist, wie man es erwarten würde. Jedes mal, wenn die Ressource, welche man committen möchte, den String „tags“ im Pfad enthält, wird diese Meldung auftauchen. Wir nutzen aber einen Paketnamen für eigene JSP Tags, welcher eben diesen String enthält (com.acme.tags.FooTag). Jedes mal, wenn man hier eine Änderung einchecken möchte, taucht die Warnung auf.

Offensichtlich ist dies nichts Besorgniserregendes, man kann die Warnung einfach ignorieren und der Commit wird anstandslos durchgeführt. Im nächsten Abschnitt soll im Detail erklärt werden, warum es zu dem Fehlverhalten kommt.

Dieser Ausschnitt aus der CommitAction Klasse ist verantwortlich für die Meldung:

1if (SVNUtility.isTagOperated(allResources)) {
2    TagModifyWarningDialog dlg = new TagModifyWarningDialog(this.getShell());
3    if (dlg.open() != 0) {
4        return;
5    }
6}
7

SVNUtility.isTagOperated() prüft die Art (~kind) des „root“-Elements der Ressource, welche committed werden soll.

1if (((IRepositoryRoot)SVNRemoteStorage.instance().asRepositoryResource(resources[i]).getRoot()).getKind() == IRepositoryRoot.KIND_TAGS) {
2    return true;
3}
4

Ich habe „root“ in Anführungsstriche gesetzt, weil man sich darüber streiten kann, was die Wurzel tatsächlich sein soll. Man nehme einfach mal folgenden Pfad als Beispiel: „/usr/local/share/svn/trunk/com/acme/tags/FooTag.java“
Ich würde sagen, dass „/“ oder „/usr/“ aus Sicht des Dateisystems oder „/trunk/“ aus der Sicht eines Repositories die Wurzel ist. Aber SVNRepositoryResource.getRoot() denkt da ganz anders:

1public IRepositoryResource getRoot() {
2    if (this.root == null) {
3        IRepositoryResource parent = this;
4        while (!(parent instanceof IRepositoryRoot)) {
5            parent = parent.getParent();
6        }
7        this.root = (IRepositoryRoot)parent;
8    }
9    return this.root;
10}
11

SVNRepositoryLocation.getParent() gibt auf Grund eines Subversion Schlüsselwortes ein entsprechendes Objekt zurück:

1Path urlPath = new Path(url);
2String name = urlPath.lastSegment();
3 
4if (location.isStructureEnabled()) {
5    if (name.equals(location.getTrunkLocation())) {
6        return new SVNRepositoryTrunk(location, url, SVNRevision.HEAD);
7    }
8    if (name.equals(location.getTagsLocation())) {
9        return new SVNRepositoryTags(location, url, SVNRevision.HEAD);
10    }
11    if (name.equals(location.getBranchesLocation())) {
12        return new SVNRepositoryBranches(location, url, SVNRevision.HEAD);
13    }
14}
15

Subversive behandelt dabei den ersten Treffer als die Wurzel: sobald ein Treffer auftaucht gibt die Methode ein entsprechendes Objekt zurück. Auf Grund des Paketnamens ist name.equals(location.getTagsLocation()) zutreffend und es wird ein SVNRepositoryTags Objekt zurück gegeben.

Nun ist die SVNRepositoryTags Klasse (welche natürlich von der Art her ein IRepositoryRoot.KIND_TAGS ist) eine Erweiterung von SVNRepositoryRootBase welche IRepositoryRoot implementiert. Hier ist der Knackpunkt, die Bedingung der while Schleife von getRoot() zieht nicht mehr an, also wird die aktuelle IRepositoryResource zurückgegeben, was dazu führt, dass SVNUtility.isTagOperated() einen positiven Test liefert – auch wenn wir uns gar nicht auf einem Tag befinden.

Dies ist natürlich nur ein kleineres Problem, da es sich hier nicht um einen Fehler, sondern nur um eine Warnung handelt. Meiner Meinung nach sollte der komplette urlPath betrachtet werden und die letzte vorkommende Instanz von IRepositoryRoot anstatt der ersten als Wurzel bzw. Indikator genutzt werden. Das würde dann auch für verschiedene Subversion Repository Layouts (Global vs. pro Projekt trunk/tags/branches) funktionieren. Die Subversion Implementierung sollte nicht vom Inhalt, in diesem Fall dem Paketnamen, abhängig sein, auch wenn Subversion Schlüsselwörter verwendet werden.

Beitrag teilen

Gefällt mir

0

//

Weitere Artikel in diesem Themenbereich

Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.

//

Gemeinsam bessere Projekte umsetzen

Wir helfen Deinem Unternehmen

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.