Praktische Softwaretechnologie Vorlesung 6 Martin Giese Johann Radon Institute for Computational and Applied Mathematics Österr. Akademie der Wissenschaften Linz PSWT 2006 28. November 2006 p.1/41
Versionsverwaltung Englisch: revision control, version control, source code management (SCM) Zweck: Verwaltung von unterschiedlichen Versionen von Quelltext Zeitliche Entwicklung Varianten, Entwicklungszweige (zeitlich parallel) PSWT 2006 28. November 2006 p.2/41
Anwendungen von Versionsverwaltung Protokollierungen von Änderungen wer hat was wann geändert Wiederherstellung von älterem Stand nach Fehlern Archivierung von alten Releases Koordinierung von gemeinsamem Zugriff durch unterschiedliche Entwickler von unterschiedlichen Rechnern Unterstützung von Entwicklungszweigen Insbes. Übertragen von Änderungen zwischen Zweigen PSWT 2006 28. November 2006 p.3/41
Repository Neue Versionen/Varianten von Dateien Repository Aktuelle oder alte Versionen von beliebigen Zweigen PSWT 2006 28. November 2006 p.4/41
Arbeitskopien Christian: Arbeitskopie Antonia: Arbeitskopie Repository Diana: Robert: Arbeitskopie Arbeitskopie PSWT 2006 28. November 2006 p.5/41
Arbeitsablauf Normaler Arbeitsablauf: Arbeitskopie von einem Zweig im Repository erstellen (checkout) Änderungen vornehmen, testen, dokumentieren, etc. Änderungen in das Repository übernehmen (checkin oder commit) Nach commit können andere Entwickler die Änderungen nutzen Alte Version auf Wunsch zugreifbar PSWT 2006 28. November 2006 p.6/41
Gleichzeitige Änderungen Problem: Antonia erstellt Arbeitskopie von Stack.java, Zweig A Diana erstellt Arbeitskopie von Stack.java, Zweig A Antonia programmiert neue Methode iterator() in Stack.java Diana verbessert den JavaDoc Kommentar von pop() Antonia checkt das geänderte Stack.java auf Zweig A ein Diana will ihre geänderte Version auf Zweig A einchecken Dianas Version enthält Antonias neue Methode nicht PSWT 2006 28. November 2006 p.7/41
Lock-Modify-Write Checkout zum Lesen immer möglich Vor Änderungen Dateien sperren (lock) Einchecken von Änderungen nur bei gesperrter Datei Nach Einchecken Sperre aufheben Fehlermeldung beim Versuch gesperrte Datei zu ändern Nur möglich bei relativ wenigen Entwicklern (Sperre aufheben wird häufig vergessen) PSWT 2006 28. November 2006 p.8/41
Beispiel Antonia erstellt Arbeitskopie von Stack.java, Zweig A Diana erstellt Arbeitskopie von Stack.java, Zweig A Antonia sperrt Datei Stack.java Diana versucht erfolglos Stack.java zu sperren. Antonia programmiert neue Methode iterator() in Stack.java Diana kocht Tee Antonia checkt das geänderte Stack.java auf Zweig A ein Diana trinkt Tee Antonia hebt die Sperre auf Stack.java auf Diana sperrt die Datei Stack.java Diana verbessert den Kommentar, etc. PSWT 2006 28. November 2006 p.9/41
Merge Version 0 Antonias Aenderungen Dianas Aenderungen Version A Version B PSWT 2006 28. November 2006 p.10/41
Merge Version 0 Antonias Aenderungen Dianas Aenderungen Version A Version B Merge PSWT 2006 28. November 2006 p.10/41
Merge Version 0 Antonias Aenderungen Dianas Aenderungen Version A Version B Merge bei disjunkten Änderungen vollautomatisch Im Fall von Konflikten, manuelle Auflösung PSWT 2006 28. November 2006 p.10/41
Copy-Modify-Merge Änderungen an Arbeitskopie ohne Sperre möglich Neue Versionen während Änderungen vor commit übernehmen Fremde Änderungen an geänderten Dateien mergen Konflikte auflösen commit möglich wenn alle fremden Änderungen übernommen Funktioniert auch mit vielen Entwicklern Viele Dateien mit kleinen Methoden gut (Konflikte unwahrscheinlicher) PSWT 2006 28. November 2006 p.11/41
Beispiel Antonia erstellt Arbeitskopie von Stack.java, Zweig A Diana erstellt Arbeitskopie von Stack.java, Zweig A Antonia programmiert neue Methode iterator() in Stack.java Diana verbessert den JavaDoc Kommentar von pop() Antonia checkt das geänderte Stack.java auf Zweig A ein Diana will ihre geänderte Version auf Zweig A einchecken Fehlermeldung: Version in Arbeitskopie veraltet Diana macht Update = Merge mit neuester Version iterator() ohne Konflikte in Stack.java eingefügt Diana checkt geänderte Version auf Zweig A ein PSWT 2006 28. November 2006 p.12/41
Update Arbeitskopie Antonia Neue Version mit iterator() Methode Arbeitskopie Diana Neue Version mit pop() JavaDoc Neue Version mit iterator() Methode und pop() JavaDoc PSWT 2006 28. November 2006 p.13/41
Versionskontrollsysteme: RCS In den frühen 80ern entwickelt Speichert Versionen für einzelne Dateien Delta-Kompression Platzsparend Lock-Modify-Write Nicht Client-Server-fähig für größere Projekte wenig geeignet PSWT 2006 28. November 2006 p.14/41
Versionskontrollsysteme: CVS Mitte der 80er entwickelt Gemeinsame Verwaltung mehrerer Dateien auf RCS aufbauend Copy-Modify-Merge Client-Server-fähig Immer noch viel benutzt Größte Nachteile: Dateien umbenennen, bewegen Commits nicht atomar PSWT 2006 28. November 2006 p.15/41
Versionskontrollsysteme: Subversion Seit Anfang 2000er entwickelt Bewußt als Ersatz für CVS Versionierung von ganzen Verzeichnisbäumen Atomares Commit Derzeit beliebteste Alternative zu CVS Erhältich von: http://subversion.tigris.org/ PSWT 2006 28. November 2006 p.16/41
Dokumentation Online-Buch: http://svnbook.red-bean.com/ FAQ: http://subversion.tigris.org/faq.html Eingebaute Kurzhilfe von der Kommandozeile: > svn help... > svn help checkout... etc. PSWT 2006 28. November 2006 p.17/41
Repository Struktur Repository speichert Folge von Versionen von Verzeichnisbäumen: Version 0 Version 1 Version 2 / / / /antonia/ /antonia/ /christian/ Hallo.java /diana/ /christian/ /robert/ /diana/ /robert/ PSWT 2006 28. November 2006 p.18/41
Repository Zugriff Repository gespeichert als Verzeichnis mit vielen Dateien Zugriff über URL: Auf selbem Rechner: file:///path/to/repository/ Mit SSH auf anderen Rechner: svn+ssh://ein.server.net/path/to/repository/ Über svnserve auf dem Server: svn://ein.server.net/repository/ Über Apache Web Server auf dem Server: http://ein.server.net/repository/ PSWT 2006 28. November 2006 p.19/41
Befehlssyntax Zugriff über svn Kommandozeilen-Client Allgemeine Befehlssyntax: svn <sub-command> <Optionen> <Argumente> sub-command: checkout, commit,... Wichtige Optionen -r: welche Revision -m "...": Commit Nachricht -N: nicht rekursiv Argumente: Betroffene Dateien in Repository oder Arbeitslopie PSWT 2006 28. November 2006 p.20/41
svn list: Dateien auflisten Repository Adresse: svn://svn.risc.uni-linz.ac.at/mgiese/pswt Inhalt auflisten: svn list svn://svn.risc.uni-linz.ac.at/mgiese/pswt (Erster Zugriff: User+Password angeben) Unterverzeichnis auflisten: svn list svn://svn.risc.uni-linz.ac.at/mgiese/pswt/martin Frühere Version: svn list -r1 svn://svn.risc.uni-linz.ac.at/mgiese/pswt PSWT 2006 28. November 2006 p.21/41
Revisionensangaben Viele Befehle nehmen eine Revision als Parameter: > svn checkout -r123 README.TXT Manche auch einen Bereich von Revisionen: > svn diff -r23:42 README.TXT Mögliche Syntax für Revisionen: Revisionsnummer: -r23 Symbole: -rhead, -rbase, -rcommitted, -rprev Zeit und Datum: -r{"2006-11-28 14:30"} PSWT 2006 28. November 2006 p.22/41
svn checkout: Arbeitskopie erstellen > svn checkout svn://.../mgiese/pswt/martin martin-work A martin-work/stack.java Checked out revision 3. Erstellt Arbeitskopie von Teil des Repository Lokales Directory martin-work martin-work/.svn enthält Verwaltungsinformation Ältere Versionen: > svn checkout -r2 svn://.../mgiese/pswt/martin martin-old... Checked out revision 2. PSWT 2006 28. November 2006 p.23/41
svn add: Neue Dateien hinzufügen Neue Datei Queue.java im Arbeitsverzeichnis anlegen Übernehmen mit (im Arbeitsverzeichnis) > svn add Queue.java A Queue.java Datei nur lokal unter Versionsverwaltung! Kann auch Verzeichnis rekursiv hinzufügen PSWT 2006 28. November 2006 p.24/41
svn stat: Zustand von Arbeitsverzeichnis sehen > svn stat A Queue.java Nach Änderung an Stack.java > svn stat A Queue.java M Stack.java A = added M = modified D = deleted usw., siehe svn help stat PSWT 2006 28. November 2006 p.25/41
svn diff: Änderungen inspizieren > svn diff Index: Stack.java =================================================================== --- Stack.java (revision 3) +++ Stack.java (working copy) @@ -5,9 +5,13 @@ /** push <code>o</code> onto this stack. */ void push(e o); - /** remove the top element from the stack and return it. */ - E pop(); /** determine whether this stack is empty. */ boolean isempty(); + + /** return the top element without deleting it */ + E peek(); + + /** remove the top element */ + E deletetop(); } PSWT 2006 28. November 2006 p.26/41
Formen für Argumente Zwischen BASE und Arbeitskopie svn diff Stack.java Zwischen älteren Versionen: svn diff -r3:4 Stack.java Oder (auch ohne Arbeitsverzeichnis): svn diff -r3:4 svn://.../martin/stack.java svn diff svn://.../stack.java@3 svn://.../stack.java@4 svn diff.../diana/stack.java@5.../antonia/stack.java@2 PSWT 2006 28. November 2006 p.27/41
svn commit: Änderungen einchecken > svn commit -m "pop durch peek und deletetop ersetzt" Adding Queue.java Sending Stack.java Transmitting file data.. Committed revision 4. Änderungen ins Repository übernommen Nur Unterschiede werden übertragen Neue Version von komplettem Verzeichnisbaum Restliche Dateien unverändert Alte Versionen auf Wunsch jederzeit zugreifbar (Mit -r Argument bei checkout) PSWT 2006 28. November 2006 p.28/41
svn update: Änderungen aus Repos. Übernehmen Checkin falls neuere Version im Repository: > svn commit -m "..." Sending Stack.java Transmitting file data.svn: Commit failed (details follow): svn: Out of date: /martin/stack.java in transaction 6-1 Änderungen im Repository seit letzem Checkout oder Update in eigene Änderungen mergen: > svn update G Stack.java Updated to revision 6. > svn commit -m "Improved JavaDoc for pop" Sending Stack.java Transmitting file data. Committed revision 7. PSWT 2006 28. November 2006 p.29/41
svn update: Resultate A = Datei hinzugefügt D = Datei gelöscht U = (lokal ungeänderte) Datei aktualisiert G = Änderungen mit lokalen gemerget C = Konflikt beim Merge Konfliktmarker in Datei: <<<<<<<.mine Version in Arbeitskopie ======= Version in Repository >>>>>>>.r8 Manuell auflösen und svn resolve aufrufen PSWT 2006 28. November 2006 p.30/41
Weitere nützliche Befehle svn log Stack.java Sämtliche checkin-kommentare auflisten svn delete Stack.java Datei in zukünftigen Versionen löschen. (kann mit svn checkout -r... wiedergeholt werden!) svn revert Stack.java Lokale Änderungen rückgängig machen (inklusive add und delete) svn blame Stack.java Wer hat welche Zeile wann eingecheckt? PSWT 2006 28. November 2006 p.31/41
Verzeichnisoperationen Verzeichnis anlegen: > svn mkdir stack A stack Datei (Verzeichnis) bewegen oder umbenennen: > svn move Stack.java stack A stack/stack.java D Stack.java (= delete + add, aber mit History) Datei (Verzeichnis) kopieren: > svn copy stack/stack.java Stack-Copy.java A Stack-Copy.java Stack-Copy.java erbt History von Stack.java Kopien sind Speicher-effizient! PSWT 2006 28. November 2006 p.32/41
Zweige und Tags In Subversion: Zweige und Tags mit svn copy realisiert. Konvention: Unterverzeichnisse > svn mkdir svn://.../mgiese/pswt/martin/branches > svn mkdir svn://.../mgiese/pswt/martin/tags > svn mkdir svn://.../mgiese/pswt/martin/trunk trunk enthält Hauptversion branches enthält ein Unterverzeichnis für jeden Zweig tags enthält ein Unterverzeichnis für jeden Tag PSWT 2006 28. November 2006 p.33/41
Beispiele Aktuelle Version taggen: > svn copy svn://.../martin/trunk svn://.../martin/tags/20061128-beispiel Konvention: Danach keine Änderungen mehr in 20061128-beispiel Seitenzweig anlegen: > svn copy svn://.../martin/trunk svn://.../martin/branches/release-1.0 Auf Seitenzweig arbeiten: > svn checkout svn://.../martin/branches/release-1.0 branch-work PSWT 2006 28. November 2006 p.34/41
svn merge: zwischen Zweigen mergen Subversion kann Unterschiede zwischen beliebigen Versionen in eine Datei im Arbeitsverzeichnis mergen: Arbeitsverzeichnis branch-work für Seitenzweig Bestimmte Änderungen aus Hauptzweig übernehmen: > svn merge -r8:9 svn://.../martin/trunk/stack.java Stack.java Subversion merkt sich nicht den merge-stand merges in Log-Nachrichten sorgfältig verzeichnen! Bei Fehlern mit svn revert --recursive rückgängig machen PSWT 2006 28. November 2006 p.35/41
Übliche Techniken/Konventionen Merge kompliziert möglichst wenige (lange) Seitenzweige Alle Entwicklungen bald auf den Hauptpfad Änderungen bald einchecken weniger Ärger mit Update-Konflikten Aber: auf Hauptpfad nur kompilierbare, getestete Checkins PSWT 2006 28. November 2006 p.36/41
Release-Zweige trunk v1.0 v1.1 v1.0 bugfix 1 rel_1.0 rel_1.1 Neuentwicklungen auf trunk Vorbereitungen für Release und Bugfixes auf Release-Zweigen Tags für releases PSWT 2006 28. November 2006 p.37/41
Aufgabe 16 Ist schon ein SVN Client vorhanden? > svn --version sollte mindestens Version 1.2 ausgeben. Sonst von http://subversion.tigris.org/project_packages.html herunterladen und installieren. Nochmal svn --version probieren! PSWT 2006 28. November 2006 p.38/41
Aufgabe 17 Das Repository für die Vorlesung ist: svn://svn.risc.uni-linz.ac.at/mgiese/pswt Darin sind Unterverzeichnisse antonia, christian, diana, martin, robert User=Dein Vorname, Paßwort=Deine Matrikelnummer (mit führender 0) Lege in Deinem Verzeichnis folgende Unterverzeichnisse an! branches, tags, trunk Checke Deine neueste Version der Stack-Aufgaben in Dein trunk Verzeichnis ein! PSWT 2006 28. November 2006 p.39/41
Aufgabe 17 (forts.) Lösche deine Arbeitskopie und checke eine neue aus! (Möglichst auch auf einem anderen Rechner probieren!) Ändere Deine Implementierung. (JavaDocs verbessern, neue Methoden isfull(), size(), etc.) Checke nach jeder abgeschlossenen Änderung ein. Schreibe dabei kurze, aussagekräftige Commit-Nachrichten! PSWT 2006 28. November 2006 p.40/41
Aufgabe 18 Lege einen Tag für die aktuelle Version in Verzeichnis tags an. Beispiel für Namen: 20061128-mit-size o.ä. Lege einen Zweig in branches an. Checke eine Änderung auf dem Zweig ein. Checke eine andere Änderung in trunk ein. Benutze svn merge um die Änderungen von trunk in den Zweig zu übernehmen. Verzeichne in der Checkin-Nachricht genau welche Änderungen von trunk im merge übernommen wurden! PSWT 2006 28. November 2006 p.41/41