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

4 Kommentare

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

svn-tag

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:

if (SVNUtility.isTagOperated(allResources)) {
	TagModifyWarningDialog dlg = new TagModifyWarningDialog(this.getShell());
	if (dlg.open() != 0) {
		return;
	}
}

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

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

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:

public IRepositoryResource getRoot() {
	if (this.root == null) {
		IRepositoryResource parent = this;
		while (!(parent instanceof IRepositoryRoot)) {
			parent = parent.getParent();
		}
		this.root = (IRepositoryRoot)parent;
	}
	return this.root;
}

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

Path urlPath = new Path(url);
String name = urlPath.lastSegment();
 
if (location.isStructureEnabled()) {
	if (name.equals(location.getTrunkLocation())) {
		return new SVNRepositoryTrunk(location, url, SVNRevision.HEAD);
	}
	if (name.equals(location.getTagsLocation())) {
		return new SVNRepositoryTags(location, url, SVNRevision.HEAD);
	}
	if (name.equals(location.getBranchesLocation())) {
		return new SVNRepositoryBranches(location, url, SVNRevision.HEAD);
	}
}

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.

Nick Prosch

Als Mitarbeiter der ersten Stunde steht Nick heute nicht mehr direkt im Dienst unserer Kunden, sondern ist als Feelgood Manager für die Mitarbeiter der codecentric da, vom Praktikanten bis zum Vorstand. Wie ein Scrum Master sieht er zu, dass ein angenehmes Arbeiten in entspannter Atmosphäre mit tollen Teams möglich ist.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Kommentare

  • Robert Spielmann

    I’d say the same about this one as I said about the camelize post: why not submit this issue to the Subclipse project? I believe that this problem is not too uncommon, especially bearing in mind that Subclipse is an Eclipse plugin, and that Eclipse is widely used for web-related Java development.

  • Michael

    Au Backe… Selbstverständlich darf die Warnung nicht vom Inhalt abhängig sein.

    Da muss ich direkt wieder an den wirklich sehenswerten Vortrag von Linus über Git denken: http://tinyurl.com/336ony

    Grüße aus Aachen,
    Michael.

  • Fabian Lange

    Robert is right, the only problem I saw after thinking half a day about it was: How would a proper way be. I see there quite many problems doing it proper. Because I do not fully agree with the conclusion that one should parse the whole path.

    what about the svnroot named „tags“ instead of svnroot? would cause problems as well. not sure though

  • Robert Spielmann

    Hello world,

    I’ve just realized that there is now a checkbox in that dialog, saying „Don’t ask any more for projects which contain tag modification.“ – cool. Should be used with caution, though – you may potentially suppress sensible warnings if you activate this option.

    Cheers
    Rob

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.