Während der aktiven Entwicklung ruht sämtlicher Code im Allgemeinen im Dateisystem auf der Festplatte der Entwickler-Workstation. Was in diesem Moment durchaus logisch und sinnvoll erscheint, ist ganz und gar nicht mehr wünschenswert, wenn die Projekte eine gewisse Größe erreichen, selbst wenn nur ein Entwickler aktiv am Code arbeitet:
Ausschließlich dateibasierte Ablagestrukturen und Datensicherungen helfen hier nur bedingt. Ein guter Ansatz zur Lösung des Problems ist die Einführung einer Software zur Versionsverwaltung. NetBeans, wie das Gros der modernen IDEs, unterstützt verschiedene Werkzeuge dieser Art.
Seit NetBeans 6.0M7 ist das 'Local History' - Feature fester Bestandteil von NetBeans, welches im Grunde genommen eine sehr einfache Versionierung für Daten in NetBeans-Projekten bereitstellt: Bei (gespeicherten) Änderungen an Dateien werden automatisch vorhergehende Versionen als eine Art 'persistentes Undo' vorgehalten, einmal vorgenommene Änderungen können somit leicht rückgängig gemacht werden. Gleichermaßen erlaubt die IDE die Wiederherstellung von gelöschten Files sowie den Vergleich von gespeicherten Ständen untereinander:
![]() |
Insgesamt stellt die 'Local History' schon wegen ständiger, konfigurationsloser Verfügbarkeit ein nützliches Werkzeug dar, welches im Notfall enorm hilfreich sein kann. In größeren Projekten kann dieses jedoch kein "richtiges" Versionsverwaltungs-System ersetzen schon aus einem einfachen Grund heraus: 'Local History' arbeitet dateibezogen; mithin kann stets nur in der Versionsgeschichte einer einzelnen Datei gearbeitet, nicht jedoch etwa ein gesamtes Projekt auf den Stand zu einem gewissen Zeitpunkt zurückgesetzt werden. Während dies für eine irrtümliche Änderung in einem .java-File angenehm ist, will man auf diese Weise nicht Änderungen revertieren, die sich über Hunderte von verschiedenen Dateien in verschiedenen Projekten erstrecken.
Das Concurrent Versioning System ist eines der am weitesten verbreiteten Versionsverwaltungs-Systeme, wird nach wie vor gerade im Umfeld der Entwicklung von Open-Source-Anwendungen (beispielsweise auf Sourceforge) massiv eingesetzt. CVS war das erste Versionierungs-Werkzeug, welches in NetBeans standardmäßig unterstützt wurde.
Die Tatsache, daß CVS trotz seiner Verbreitung gewisse Nachteile mit sich bringt (u.a. im Hinblick auf die Versionierung von Binärdateien sowie die fehlende Transaktionsunterstützung), war ursprünglich der Grund für die Entwicklung von Subversion, das explizit als Nachfolger von CVS angedacht ist und viele dieser Schwächen kompensiert. Trotz verschiedener Kritikpunkte (etwa der Tatsache, daß, im Gegensatz zu CVS, das Repository keine einzelnen Dateien, sondern eine BerkeleyDB-basierende Datenbank und entsprechend nur mit speziellen Tools zu handhaben ist) stellt Subversion dieser Tage ein robustes und verläßliches Versionsverwaltungs-System dar und wird von NetBeans seit Version 5.5 unterstützt.
Als relativ neues System wird in NetBeans 6 auch Mercurial als dezentraler, relativ neuer Ansatz der Versionsverwaltung unterstützt, nicht zuletzt aus dem Grund, daß seit einiger Zeit auch die Migration der NetBeans-Sources dorthin vorgenommen wird. Im Gegensatz zu SVN oder CVS existiert in Mercurial nicht die Wahrnehmung eines "zentralen" Repository und lokaler "Arbeitskopien" auf den Maschinen der Nutzer; vielmehr existieren unter Umständen mehrere Repositories auf mehreren Maschinen, zwischen denen der Abgleich auf Change-Set - Basis erfolgt.
Bekanntlich sind sowohl CVS als auch Subversion, obwohl im Wesentlichen in Verbindung mit Repository-Servern bekannt, auch in der Lage, Versions-Bestände in Verzeichnissen auf einer lokalen Festplatte vorzuhalten. Exemplarisch soll daher die Nutzung von Versionierung in NetBeans 6.0 demonstriert werden anhand eines lokalen Subversion-Repositories.
Für Subversion muß die Arbeitsumgebung zwei Bedingungen erfüllen, um dieses VM-System mit NetBeans nutzen zu können:
Neben dem Erfordernis, ein lokales Repository zu erzeugen, setzt auch das NetBeans-SVN-Modul direkt auf den svn-Werkzeugen der zugrundeliegenden Plattform auf, was den Vorteil hat, daß die Versionierung für von NetBeans verwaltete Projekte auch ohne NetBeans mit "SVN-Bordmitteln" einfach möglich ist.
Mit dem Befehl svnadmin create local läßt sich schnell ein SVN-Versionsbestand erzeugen, der aus NetBeans heraus nutzbar ist. Im Beispiel wird das Repository als Unterverzeichnis von $HOME/.repository/ erzeugt und "local" benannt. Danach findet sich im bewußten Verzeichnis die Struktur, die in Folge die Versionen des Codes aus dem Beispielprojekt aufnehmen wird:
![]() |
Um das lokale Repository mit Leben zu befüllen, soll ein leeres Projekt in NetBeans erstellt werden, im Beispiel vom Typ 'Java Application', allerdings ohne eine Hauptklasse zu erzeugen:
![]() |
Im Ergebnis entsteht ein leeres Projektverzeichnis mit grundlegender NetBeans-Build-Infrastruktur für Sources und Tests sowie zwei angehängten JUnit-Libraries. Um den Effekt von Versionierung im Hinblick auf Änderungen zu testen, soll das Projekt schon in diesem leeren Urzustand in das lokale Repository eingepflegt werden. Dies geschieht über Rechtsklick auf das Projekt -> 'Versioning' -> 'Import into Subversion Repository',...
![]() |
... worauf der SVN-Assistent zur Anzeige kommt und zunächst um Eingabe des URL zu einem existenten Repository bittet (SVN-Bestände lassen sich über verschiedene Protokolle erreichen, u.a. HTTP, SSH, FTP oder eben auch lokalen Dateisystem-Zugriff). Hier ist auf das vorangehend erzeugte lokale Leer-Repository "local" zu verweisen:
![]() |
Fortsetzend mit "Next", erwartet die IDE die Eingabe einer 'Commit Message', die als Text mit der in das Repository importierten Version des Codes gespeichert wird und im "Ernstfall" Aussagen über die Änderungen seit der letzten Version beinhalten sollte:
![]() |
Im Folgenden ('Next') können dann die Dateien und Verzeichnisse ausgewählt werden, die mit dem Projekt in das Repository zu importieren sind. Im gegenwärtigen, neu erzeugten, leeren Java-Projekt ist dies bislang nur die Infrastruktur, die NetBeans für Verwaltung und Build benötigt:
![]() |
Bedarfsweise können hier auch (über Auswahl einer entsprechenden 'Commit Action') Dateien vom Import ausschließen, was insbesondere dann interessant ist, wenn beispielsweise maven2-Projekte "pur", ohne IDE-spezifische Projektinformationen, versioniert werden sollen. Nach Abschluß mit "Finish" wird der Import der Dateien durch svn tatsächlich vorgenommen. Danach ist das Projekt lokale Arbeits-Kopie eines SVN-Repositories, was sich an verschiedenen Punkten erkennen läßt:
![]() |
![]() |
![]() |
Um die Versionierung in Aktion zu sehen, soll nun Code in das Projekt eingeführt werden in Form einer Klasse MyApplication über Rechtsklick auf 'Source Packages' im Projekt -> 'New' -> 'Java Class':
![]() |
Mit 'Finish' erzeugt der Assistent sowohl das erforderliche Java-Package als auch die Datei MyApplication.java im Projekt, womit sich das Projekt-Verzeichnis im Vergleich zu der im SVN-Repository gespeicherten Version ändert. Die IDE zeigt dies auch sofort an (Eine vollständige Liste der Versioning-Markierungen und -Farben findet sich in der offiziellen (englischen) 'Guided Tour of Subversion...' in der NetBeans-Knowledge-Base):
![]() |
Um diese Änderung ins Versioning-Repository zu übertragen, ist die Option 'Commit' im Menü 'Versioning' oder im 'Subversion'-Kontextmenü des Projektes zu wählen, worauf ein Assistent in schon bekannter Struktur die Möglichkeiten bietet, eine Commit Message anzugeben sowie für die seit der letzten Version geänderten Dateien auszuwählen, ob und wie diese in die Versionierung importiert werden sollen. Es zeigt sich:
![]() |
Mit dem Einfügen der Klasse in das definierte Paket werden die damit verbundenen Verzeichnisse sowie die .java-Datei neu in den Bestand aufgenommen (die Änderung an nbproject ist verbunden mit der Tatsache, daß das Projekt in Versionierung aufgenommen wurde, und soll daher ignoriert werden):
![]() |
In der Arbeit mit Code-Projekten ist die Verwendung von Versionierungs-Systemen leicht einsehbar. Darüber hinaus bieten jedoch sowohl Werkzeuge wie Subversion als auch die NetBeans-IDE die Möglichkeit, neben Programmcode quasi beliebige Datei- und Ordnerstrukturen in einem zentralen Repository abzulegen.
Dafür ist zunächst, im "Favorites"-Fenster, über Rechtsklick -> "Add to Favorites" das bewußte Basis-Verzeichnis zu den Favoriten hinzuzufügen (im Beispiel das Verzeichnis, in dem ich die Screenshots für diese Tutorials speicher) , ...
![]() |
... bevor über "Versioning" -> "Subversion" -> "Import into Repository" das Verzeichnis in Versionierung übernommen werden kann:
![]() |
Hierbei ist zu berücksichtigen: Anders als im "Projects"-Window ist diese Möglichkeit in "Favorites" nicht über das Kontext-Menü des Ordners verfügbar, sondern nur über das Hauptmenü der IDE. Dies gilt indes nur für den erstmaligen Import - ist das Verzeichnis einmal versioniert, läßt sich wie gewohnt die Subversion-Funktionalität über Rechtsklick auf das Verzeichnis aufrufen:
![]() |
Im Nachgang läßt sich der Datenordner wie ein beliebiges Code-Projekt über das Repository versionieren. Was zunächst wie Spielerei und eher "Nebenaspekt" einer Technik wirkt, die eben doch vorrangig bei der Software-Entwicklung zum Einsatz kommt, läßt sich durchaus plausibel als "sinnvoll" begründen:
| vers-01-localdiff.jpg | ![]() |
102434 bytes |
| vers-02-localrep.jpg | ![]() |
46866 bytes |
| vers-03-emptyproject.jpg | ![]() |
35515 bytes |
| vers-04-importproject.jpg | ![]() |
67194 bytes |
| vers-05-addrepo.jpg | ![]() |
26059 bytes |
| vers-06-commitmessage.jpg | ![]() |
37896 bytes |
| vers-07-files.jpg | ![]() |
71200 bytes |
| vers-08-versioned.jpg | ![]() |
15513 bytes |
| vers-09-history.jpg | ![]() |
71459 bytes |
| vers-10-history2.jpg | ![]() |
58567 bytes |
| vers-11-history3.jpg | ![]() |
45355 bytes |
| vers-12-addclass.jpg | ![]() |
29621 bytes |
| vers-13-classadded.jpg | ![]() |
16375 bytes |
| vers-14-commitclass.jpg | ![]() |
60977 bytes |
| vers-15-commitoutput.jpg | ![]() |
90593 bytes |
| vers-16-fave.jpg | ![]() |
35256 bytes |
| vers-17-import.jpg | ![]() |
21914 bytes |
| vers-18-syncfave.jpg | ![]() |
51230 bytes |