Inhaltsverzeichnis
Zusammenfassung
Der Einsatz von Subversion zur Pflege der eigenen Pakete und zur kollaborativen Entwicklung wird vorgestellt.
Ein Versionskontrollsystem zu verwenden, hat eine Reihe von Vorteilen. So speichert es alle Versionsstände der Vergangenheit in einer effizienten Art und Weise. Mit Hilfe von Tags können einzelne Versionen noch einmal mit einem frei wählbaren Begriff besonders gekennzeichnet werden. Unterschiede zwischen verschiedenen Versionen können leicht dargestellt werden und man kann jederzeit zu älteren Versionen zurückkehren, wenn man sich vertan hat. Mittels branching ist die Pflege von beispielsweise experimentellen Parallelversionen möglich.
Benutzt man ein zentrales Repository, so hat man vollen Zugriff von jedem beliebigen Rechner aus und das wiederum ermöglicht eine kollaborative Entwicklung im Team. Subversion verringert mögliche Konflikte und vermeidet Datenverlust, in dem es fremde Änderungen nicht einfach überschreibt, sondern weitgehend automatisch zusammenführt.
Es gibt eine Reihe von verschiedenen Versionskontrollsystemen, welche wahrscheinlich alle mehr oder weniger für Debianpakete geeignet sind. Ich werde mich auf Subversion beschränken, dem Nachfolger von CVS, weil es leicht erlernbar und weit verbreitet ist. Es gibt viel Dokumentation dafür sowie eine Anzahl grafischer Frontends.
Beispiel 1.1. Voraussetzungen für die Nutzung von Subversion
$ sudo apt-get install build-essential devscripts fakeroot meld svn-buildpackage Paketlisten werden gelesen... Fertig Abhängigkeitsbaum wird aufgebaut... Fertig ... $ sudoedit /etc/apt/sources.list $ sudo apt-get update ... Es wurden 11,8kB in 2s geholt (5247B/s) Paketlisten werden gelesen... Fertig
Zunächst müssen einige Pakete installiert werden. Weiterhin sollte ein
Quelle für Sourcepakete in
/etc/apt/sources.list
in folgender Form vorhanden sein:
deb-src http://ftp.de.debian.org/debian unstable main contrib non-free
Und zum Schluss sollte noch einmal die apt-Datenbank aktualisiert werden.
Beispiel 1.2. Beispiel für die Nutzung von Subversion
$ svnadmin create ~/svnroot
$ export SVN=file://$HOME/svnroot
$ svn-inject -o -c0 acpid_1.0.4-7.1.dsc $SVN
...
Übertrage Daten ................
Revision 4 übertragen.
Done!
Removing tempdir /tmp/tmp.epQdN12567.
$ svn list $SVN
acpid/
$ svn list $SVN/acpid
branches/
tags/
trunk/
$ svn checkout $SVN/acpid/trunk acpid
A acpid/acpi_listen.8
A acpid/acpid.c
A acpid/ud_socket.c
...
Ausgecheckt, Revision 4.
$ cd acpid
$ sensible-editor debian/README.debian
$ debchange -i
$ meld .
$ sudo apt-get build-dep acpid
Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut... Fertig
0 aktualisiert, 0 neu installiert, 0 zu entfernen und 0 nicht aktualisiert.
$ svn-buildpackage --svn-ignore
Imported config directives:
--svn-builder=debuild -uc -us
--svn-no-links
...
Binary package:
/home/twerner/build-area/acpid_1.0.4-7.2_i386.deb
rm -rf /home/twerner/build-area/acpid-1.0.4
$ svn status
M debian/changelog
M debian/README.debian
$ svn commit
Sende debian/README.debian
Sende debian/changelog
Übertrage Daten ..
Revision 5 übertragen.
$ svn-buildpackage --svn-tag
...
svn -m [svn-buildpackage] Tagging acpid (1.0.4-7.2) cp file:///home/twerner/svnroot/acpid/trunk file:///home/twerner/svnroot/acpid/tags/1.0.4-7.2
Revision 6 übertragen.
dch -D UNRELEASED -i NOT RELEASED YET
I: Done! Created the next changelog entry, please commit later or revert.
rm -rf /home/twerner/build-area/acpid-1.0.4
Für einen Test brauchen wird ein SVN-Repository, welches sich unter
einer URL ansprechen, für die wir gleich eine Variable
in ~/.bashrc definieren.
Wer mehrere Repositories nutzt, muss dafür verschiedene Variablen definieren.
Im folgenden werden wir mit dem Paket acpid arbeiten, welches wir
zunächst in Quellform herunterladen:
http://debianpaket.de/acpid/acpid_1.0.4.orig.tar.gz,
http://debianpaket.de/acpid/acpid_1.0.4-7.1.diff.gz sowie
http://debianpaket.de/acpid/acpid_1.0.4-7.1.dsc
und dann ins Repository importieren. Dann sehen wir, dass es im
Repository ein Verzeichnis acpid gibt, das
wiederum 3 Unterverzeichnisse trunk,
tags und branches hat, wobei
trunk den Inhalt des Debianpakets enthält, den
wir gleich auschecken. Der Befehl wäre übrigens auch automatisch von
svn-inject aufgerufen wurden, wenn es ohne -c0 aufgerufen wird.
Das neue lokale Verzeichnis acpid enthält nun alle Dateien, die durch
acpid_1.0.4-7.1.diff.gz hinzugefügt oder geändert
werden. Unveränderte Dateien aus
acpid_1.0.4.orig.tar.gz wurden aufgrund der
Option -o nicht zum Repository hinzugefügt. Nun ändern wir die Datei
debian/README, fügen einen changelog-Eintrag
hinzu und schauen uns die Änderungen an. Dann installieren wir die
Build-Depends und bauen das Paket. Die Option --svn-ignore ist
notwendig, weil wir lokale Änderungen noch nicht wieder eingecheckt
haben, was wir auch mit sehen. Das Paket wird im Verzeichnis
../build-area gebaut und das Ergebnis ist dort zu
finden, was den Vorteil hat, dass keine generierten Dateien im
Arbeitsverzeichnis zurück bleiben. Sobald wir damit zufrieden sind,
können wir die Änderungen committen wobei ein Editor startet, in dem
man eine Logmeldung eintragen sollte. Schließlich taggen wir die
Version noch mittels oder, wenn wir uns den erneuten Build sparen
wollen, ergänzen wir --svn-tag-only. In diesem Zusammenhang gibt es
noch die Option --svn-retag, falls wir einen versehentlich falsch
gesetzten Tag überschreiben wollen.
Mit Meld kann man sich bequem die lokalen Änderungen noch einmal anschauen, bevor man sie ins Repository eincheckt.

Neue Dateien und Verzeichnisse muss man mit
svn add
erst bekannt machen, ansonsten werden sie von svn-buildpackage komplett ignoriert. Für Verzeichnisse gibt es noch das Kommando
svn mkdir
welches sowohl das Verzeichnis lokal erstellt als auch mit automatisch registriert.
svn remove
entfernt Dateien sowohl aus dem Dateisystem als auch aus Subversion.
svn copy
und
svn move
sind Varianten von add und rm unter Erhalt der bereits vorhandenen Versionsgeschichte; copy wird u.a. zum Taggen und Branchen eingesetzt.
svn revert
verwirft alle lokalen und noch nicht eingecheckten Änderungen an einer Datei und mit der Option -R auch rekursiv für ganze Verzeichnisbäume.
Eine Besonderheit von Subversion sind die Properties, also Metadaten für Dateien und Verzeichnisse. Mit
svn propset svn:executable debian/rules '*'
markiert man debian/rules als ausführbar, die Umkehrung ist
svn propdel svn:executable debian/control
Mit
svn propedit svn:ignore
kann man im Editor Patterns für zu ignorierende Dateien z.B. Backups
eingeben. svn-inject -o setzt die Property mergeWithUpstream auf den
Wert 1 für das Verzeichnis debian, um anzuzeigen,
dass unmodifizierte Upstreamdateien nicht in SVN eingecheckt wurden.
svn status --show-updates
zeigt an, ob jemand anderes einen commit durchgeführt hat und welche Dateien geändert wurden. Die konkreten Änderungen kann man sich mittels
svn diff --revision HEAD
anschauen und mit
svn update
lokal einspielen. Letzteres ist unbedingt notwendig, bevor man selbst wieder committen kann. svn update versucht, eventuelle eigene Änderungen mit Änderungen anderer zu mergen. Selten auftretende Konflikte muss man aber von Hand lösen.
Zunächst laden wir eine neue Upstream-Version herunter: http://debianpaket.de/acpid/acpid-1.0.6.tar.gz und das Upgrade wird mit svn-upgrade durchgeführt wie im folgendem Beispiel. Unter Umständen kann es hier zu Konflikten kommen, die man manuell auflösen muss.
Beispiel 1.3. Upstream-Updates
$ svn-upgrade ../acpid-1.0.6.tar.gz ... debchange -D UNRELEASED -v "1.0.6-1" "(NOT RELEASED YET) New upstream release" Done! Last commit pending, please execute manually. Process ended with code 0 $ svn diff Index: debian/changelog =================================================================== --- debian/changelog (Revision 5) +++ debian/changelog (Arbeitskopie) @@ -1,3 +1,9 @@ +acpid (1.0.6-1) UNRELEASED; urgency=low + + * (NOT RELEASED YET) New upstream release + + -- Torsten Werner <twerner@debian.org> Sat, 15 Sep 2007 21:15:23 +0200 + acpid (1.0.4-7.2) unstable; urgency=low * test
Komplett neue Pakete beginnt man am einfachsten zunächst ohne SVN und importiert sie später mit
svn-inject -o
In späteren Kapiteln werden eleganter Methoden vorgestellt, die aber weitere Änderungen am Paket voraussetzen.
Pakete, die in einem SVN-Repository gepflegt werden, sollten um 2
Header im Sourcebereich von debian/control
erweitert werden: Vcs-Svn und Vcs-Browser, wobei letztere
Variable eine URL sein soll, die im Webbrowser aufgerufen werden kann.
Im folgenden Beispiel wird ein Paket verwendet, welches im Gegensatz
zu acpid tatsächlich Subversion einsetzt.
Beispiel 1.4. Vcs-Header in debian/control
Vcs-Svn: svn+ssh://svn.debian.org/svn/collab-maint/deb-maint/afbackup/trunk Vcs-Browser: http://svn.debian.org/wsvn/collab-maint/deb-maint/afbackup/trunk
Weitere Optionen, die svn-buildpackage nicht kennt, gibt es einfach an
das Buildkommando weiter, z.B. -S, welches nur ein Quellpaket und
keine Binärpakete baut. Das Tool ist über einen Datei
~/.svn-buildpackage.conf konfigurierbar:
Beispiel 1.5. Konfiguration für svn-buildpackage
svn-builder=debuild -uc -us svn-no-links svn-dont-clean
In diesem Fall wird debuild zum Bauen aufgerufen, ohne zu signieren,
es wird keine Optimierung über hard links durchgeführt und wird das
clean target nicht separat aufgerufen, weil das bereits debuild
übernimmt. Eine Alternative dazu ist die Konfiguration über
SVN-Properties. Gelegentlich braucht man nicht nur den Inhalt des
Debian-Diffs sondern des kompletten Pakets in ausgepackter Form. Mit
svn-buildpackage --svn-export
wird das Paket komplett in ../build-area ausgepackt.
Das Buch "Version Control with Subversion" gibt es unter
http://svnbook.red-bean.com.
Dokumentation zu svn-buildpackage gibt es unter
/usr/share/doc/svn-buildpackage/HOWTO.html/index.html
und online unter
http://debianpaket.de/svn-buildpackage/index.html.
Gegenüber seinem Vorgänger CVS cached SVN mehr Daten lokal und funktioniert damit besser offline. Außerdem beherrscht es atomare commits und erleichtert branching und merging. Für echte verteilte Versionskontrolle sind andere Systeme besser geeignet wie beispielsweise SVK (eine Erweiterung von SVN), arch/bazaar (von Ubuntu verwendet) oder git, was in einem späteren Artikel vorgestellt wird. Es gibt eine Reihe von grafischen Frontends wie svn-workbench, subcommander, kdesvn, subclipse und meld. Meld stellt Diffs wie im folgendes Bildschirmfoto sehr übersichtlich dar und beherrscht die grundlegenden SVN-Kommandos. Allerdings ist es kein vollwertiger SVN-Client, da bietet beispielsweise kdesvn mehr.
