Programmieren mit Harald R. Haberstroh (original) (raw)
Mercurial ist ein Version Control System (abk. VCS, dt. Versionsverwaltungssystem). Software-Entwickler verwenden es um ihren Source Code zu verwalten. Zweck von Mercurial ist:
- Verwalten (und Speichern) aller alten Versionen von jeder Datei
- Verschiedene Versionen des Source Codes zusammenführen, sodass Team-Mitglieder unabhängig voneinander am Code arbeiten können um dann ihre Änderungen wieder zusammenzuführen.
Ohne Versionsverwaltung müsste man die verschiedenen Versionen in Verzeichnissen mit unterschiedlichen Namen speichern:
hh@knuth:~/Dokumente/mercurial-demo$ ls -l insgesamt 20 drwxrwxr-x 2 hh hh 4096 Sep 18 17:44 Copy (2) of CountDown drwxrwxr-x 2 hh hh 4096 Sep 18 17:44 Copy (3) of CountDown drwxrwxr-x 2 hh hh 4096 Sep 18 17:44 Copy of CountDown drwxrwxr-x 2 hh hh 4096 Sep 18 17:44 CountDown drwxrwxr-x 2 hh hh 4096 Sep 18 17:44 CountDown 2012-09-18
Das ist mühsam und verwirrend und benötigt eine Menge Speicherplatz (das Projekt ist dann praktisch vollständig in jeder Kopie des Projektverzeichnisses). Mit einem VCS kann man das viel besser machen.
Die meisten arbeiten mit Mercurial auf der Kommandozeile. Das funktioniert völlig identisch unter Linux, Windows und Mac. Das Kommando ist hg:
hh@knuth:~/Dokumente/mercurial-demo$ hg Mercurial Distributed SCM
Grundlegende Befehle:
add Fügt die angegebenen Dateien der nächsten Version hinzu annotate Zeigt Informationen über Änderungssätze pro Dateizeile an clone Erzeugt eine Kopie eines bestehenden Projektarchivs commit Übernimmt Änderungen der angegebenen Dateien oder alle ausstehenden Änderungen ins Archiv diff Zeigt Änderungen des Projektarchivs oder angegebener Dateien an export Gibt Kopfzeilen und Änderungsverlauf einer oder mehrerer Versionen aus forget Angegebene Dateien ab dem nächsten Commit nicht mehr unter Versionskontrolle stellen init Erzeugt ein neues Projektarchiv im angegebenen Verzeichnis log Zeigt die Revisionshistorie des Archivs oder von Dateien an merge Führt das Arbeitsverzeichnis mit einer anderen Revision zusammen pull Holt Änderungen aus dem angegebenen Projektarchiv push Überträgt lokale Änderungen in das angegebene Ziel remove Entfernt die angegebenen Dateien in der nächsten Version serve Startet einen eigenständigen Webserver status Zeigt geänderte Dateien im Arbeitsverzeichnis summary Fasst den Status des Arbeitsverzeichnisses zusammen update Aktualisiert das Arbeitsverzeichnis (oder wechselt die Version)
Nutze "hg help" für eine Liste aller Befehle oder "hg -v" für Details
Vielfach ist das Betriebssystem auf englisch eingestellt:
hh@knuth:~/Dokumente/mercurial-demo$ hg Mercurial Distributed SCM
basic commands:
add add the specified files on the next commit annotate show changeset information by line for each file clone make a copy of an existing repository commit commit the specified files or all outstanding changes diff diff repository (or selected files) export dump the header and diffs for one or more changesets forget forget the specified files on the next commit init create a new repository in the given directory log show revision history of entire repository or files merge merge working directory with another revision pull pull changes from the specified source push push changes to the specified destination remove remove the specified files on the next commit serve export the repository via HTTP status show changed files in the working directory summary summarize working directory state update update working directory
use "hg help" for the full list of commands or "hg -v" for details
Im weiteren werden Sie nur mehr die englischen Ausgaben sehen!
Um Mercurial verwenden zu können, muss noch eine Konfigurationsdatei .hgrc im Homeverzeichnis angelegt werden:
hh@knuth:~ $ cat > .hgrc [ui] username = Name user@email.com hh@knuth:~ $
Name und E-Mail muss natürlich sinnvoll sein (z.B. Manfred Bauer mbauer10922@gmail.com). Die Datei kann natürlich mit jedem Texteditor angelegt werden.
Um eine Versonsverwaltung zu verwenden, benötigt man ein Repository (dt Lager, Magazin). Das Repository speichert alle alten Versionen aller Dateien eines Verzeichnisses. Natürlich wird ein platzsparendes Verfahren verwendet. Es werden die Dateien plus aller Änderungen gespeichert.
Früher war das Anlegen eines Repositories ziemlich mühsam. Mit Mercurial geht das ganz einfach: einfach ins Hauptverzeichnis des Projekts (des Dateibaums) wechseln und hg init eingeben.
hh@knuth:/Dokumente/mercurial-demo$ cd c2bf
hh@knuth:/Dokumente/mercurial-demo/c2bf$ ls -a
. .. .project 1tox GPL Makefile README cc ld math strip test.sh wrapper
hh@knuth:/Dokumente/mercurial-demo/c2bf$ hg init
hh@knuth:/Dokumente/mercurial-demo/c2bf$
Was ist nun passiert? Ein Verzeichnis .hg wurde angelegt:
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ ls -a . .. .hg .project 1tox GPL Makefile README cc ld math strip test.sh wrapper
.hg ist das Repository. Ein Verzeichnis mit allem Drum und Dran für Mercurial. Einstellungen, alte Versionen von Dateien, Tags (dt Etiketten, Marken), ein paar extra Socken, wenn es kalt wird usw. In dem Verzeichnis hat man nichts verloren, man sollte da nicht händisch herumdrehen, da könnte was kaputt gehen.
Das Repository ist noch leer. Die Dateien müssen noch hinzugefügt werden.
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ hg add adding .project adding 1tox/BF1to2.txt adding 1tox/BF1to4.txt adding 1tox/Makefile adding 1tox/MultiBitwidth.txt adding 1tox/c2bf-1to16bit adding 1tox/c2bf-1to2 adding 1tox/c2bf-1to2.c adding 1tox/c2bf-1to2.o adding 1tox/c2bf-1to32bit adding 1tox/c2bf-1to4 adding 1tox/c2bf-1to4.c adding 1tox/c2bf-1to4.o adding GPL adding Makefile adding README adding cc/Makefile adding cc/README.txt
uswusf...viele Dateien...
hh@knuth:~/Dokumente/mercurial-demo/c2bf$
Ein Schritt fehlt noch... die Änderungen müssen committed (commit - übergeben) werden. Welche Änderungen?
Das Hinzufügen der neuen Dateien.
Commit sagt Mecurial, dass der aktuelle Dateibestand als neue Version übernommen werden soll. Solange kein commit erfolgt, wird im Repository nichts geändert.
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ hg commit
Mercurial öffnet nun einen Editor (bei mir vim), sodass eine Nachricht eingegeben werden kann. Diese Nachricht ist eine Erinnerung für den Programmierer, die beschreiben soll, was sich geändert hat.
Initial version of the c2bf code.
HG: Enter commit message. Lines beginning with 'HG:' are removed. HG: Leave message empty to abort commit. HG: -- HG: user: hh HG: branch 'default' HG: added .project HG: added 1tox/BF1to2.txt HG: added 1tox/BF1to4.txt HG: added 1tox/Makefile HG: added 1tox/MultiBitwidth.txt HG: added 1tox/c2bf-1to16bit HG: added 1tox/c2bf-1to2 HG: added 1tox/c2bf-1to2.c HG: added 1tox/c2bf-1to2.o HG: added 1tox/c2bf-1to32bit HG: added 1tox/c2bf-1to4 HG: added 1tox/c2bf-1to4.c HG: added 1tox/c2bf-1to4.o HG: added GPL HG: added Makefile HG: added README HG: added cc/Makefile HG: added cc/README.txt HG: added cc/ast.h HG: added cc/c2bf-cc HG: added cc/c2bf-dispast "/tmp/hg-editor-eMVxZ3.txt" 204L, 6635C
Im vim muss man zuerst I (großes i) dann gleich den Text eingeben. Mit (Esc-Taste) und :x (Eingabetaste) speichern.
Mit hg log bekommt man eine Liste der Änderungen.
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ hg log changeset: 0:3d54225035a3 tag: tip user: hh date: Tue Sep 18 21:00:02 2012 +0200 summary: Initial version of the c2bf code.
Jetzt ändern wir eine Datei:
So, nun Übergeben wir die Änderung an Mercurial: hg commit
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ hg commit
Mercurial erkennt die Änderung und bietet wieder den Editor für die Commit-Nachricht an:
Added comment.
HG: Enter commit message. Lines beginning with 'HG:' are removed.
HG: Leave message empty to abort commit.
HG: --
HG: user: hh
HG: branch 'default'
HG: changed test.sh
~
~
~
~
~
hg log zeigt nun folgendes an:
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ hg log changeset: 1:ad33e88c004f tag: tip user: hh date: Tue Sep 18 21:24:58 2012 +0200 summary: Added comment.
changeset: 0:3d54225035a3 user: hh date: Tue Sep 18 21:00:02 2012 +0200 summary: Initial version of the c2bf code.
hg log funktioniert wie ein Blog: das Neuseste wird zuoberst angezeigt.
Werden versehentlich Dateien gelöscht oder nicht funktionierende Änderungen im Sourcecode gemacht, kann man mit hg revert --all die Änderungen bis zum letzten Commit zurücknehmen.
--all nimmt alle Änderungen aller Dateien zurück.
Statt --all kann eine Liste von Dateien angegeben werden, für die man die Änderungen zurücknehmen will.
Wenn Sie mit Mercurial an einem Projekt arbeiten, dann sollten Sie folgendermaßen vorgehen:
- Mache ein paar Änderungen
- Schau, ob sie funktionieren
- Funktionieren sie, dann hg commit
- Andernfalls hg revert --all
- GOTO 1
Will man wissen, welche Dateien sich geändert haben, kann man hg status verwenden:
hh@knuth:/Dokumente/mercurial-demo/c2bf$ ls
1tox GPL Makefile README cc ld math strip test.sh wrapper
hh@knuth:/Dokumente/mercurial-demo/c2bf$ vim test.sh
hh@knuth:/Dokumente/mercurial-demo/c2bf$ cp test.sh testall.sh
hh@knuth:/Dokumente/mercurial-demo/c2bf$ rm GPL
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ hg status
M test.sh
! GPL
? testall.sh
M bedeutet modified, also geändert. ! bedeutet fehlend, die Datei war beim letzten Commit noch da, ist aber nun verschwunden. ? bedeutet unbekannt, Mercurial weiß von dieser Datei (noch) nichts.
Will man nun wissen, was sich in einer Datei geändert hat, kann man hg diff verwenden:
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ hg diff test.sh diff -r ad33e88c004f test.sh --- a/test.sh Tue Sep 18 21:24:58 2012 +0200 +++ b/test.sh Tue Sep 18 21:54:11 2012 +0200 @@ -1,5 +1,6 @@ #!/bin/bash
run tests with c2bf
+# BFI=egobfi16
Test 1
Das ist etwas kryptisch, aber oft verwendet man eine IDE, welche die Änderungen schön anzeigt. mit gvim und ein paar Shell-Tricks bekommt man das auch hin.
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ *hg cat test.sh | * gvim - -c ":vert diffsplit test.sh" -c 'map q :qa!'
Damit die Änderungen von oben committed werden können, müssen noch das ! und ? behandelt werden. Dass die Datei GPL gelöscht wurde, muss mit hg remove gekanntgegeben werden und die neue Datei testall.sh muss mit hg add Mercurial bekannt gemacht werden:
hh@knuth:/Dokumente/mercurial-demo/c2bf$ hg status
M test.sh
! GPL
? testall.sh
hh@knuth:/Dokumente/mercurial-demo/c2bf$ hg remove GPL
hh@knuth:/Dokumente/mercurial-demo/c2bf$ hg st
M test.sh
R GPL
? testall.sh
hh@knuth:/Dokumente/mercurial-demo/c2bf$ hg add
adding testall.sh
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ hg st
M test.sh
A testall.sh
R GPL
A bedeutet nun added (hinzugefügt) und R removed (gelöscht).
Die Änderungen werden aber erst mit hg commit ins Repository übernommen!
Übrigens kann man die hg-Kommandos abkürzen, wie man beim letzten Beispiel sieht. Man benötigt nur so viele Zeichen bis das Kommando eindeutig ist.
Nach dem Commit, sieht das Log so aus:
hh@knuth:/Dokumente/mercurial-demo/c2bf$ hg com
hh@knuth:/Dokumente/mercurial-demo/c2bf$ hg log
changeset: 2:a8ff7f27bcaf
tag: tip
user: hh harald@haberstroh.at
date: Tue Sep 18 22:24:30 2012 +0200
summary: some major changes.
changeset: 1:ad33e88c004f user: hh harald@haberstroh.at date: Tue Sep 18 21:24:58 2012 +0200 summary: Added comment.
changeset: 0:3d54225035a3 user: hh harald@haberstroh.at date: Tue Sep 18 21:00:02 2012 +0200 summary: Initial version of the c2bf code.
hh@knuth:/Dokumente/mercurial-demo/c2bf$ hg status
hh@knuth:/Dokumente/mercurial-demo/c2bf$
/harald@haberstroh.at/harald@haberstroh.at/harald@haberstroh.at
Beim Log zeigt changeset die Versionsnummern an. Die Versionsnummern bestehen aus zwei Teilen, einer "lesbaren" Zahl wir 0 (initiale Version) oder 1 sowie nach dem : eine komische Hexadezimalzahl, welche meist "ignoriert" werden kann.
Wie man sieht, zeigt nun hg status nichts mehr an, alle Änderungen wurden übernommen.
Mit hg cat kann man sich jede beliebige Version einer Datei aus dem Repository anzeigen lassen. Mit der Option -r [zahl] (-r wie revision) kann man sich die Version mit der Nummer [zahl] anzeigen lassen.
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ hg cat test.sh #!/bin/bash
run tests with c2bf
BFI=egobfi16
Test 1
uswusf...viele Zeilen...
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ hg cat -r 0 test.sh #!/bin/bash BFI=egobfi16
Test 1
uswusf...viele Zeilen...
Übrigens kann die Option -r [zahl] auch bei hg diff verwendet werden:
hh@knuth:~/Dokumente/mercurial-demo/c2bf$ hg diff -r 0 test.sh diff -r 3d54225035a3 test.sh --- a/test.sh Tue Sep 18 21:00:02 2012 +0200 +++ b/test.sh Tue Sep 18 22:41:20 2012 +0200 @@ -1,4 +1,6 @@ #!/bin/bash +# run tests with c2bf +# BFI=egobfi16
Test 1
Mit hg update kann man den Inhalt des aktuellen Verzeichnisses auf jede beliebige Version setzen. hg update -r 279999 liefert leider keine super coole SciFi Version mit Laserschwertern unseres Projekts. Jede Version in der Vergangenheit ist aber möglich. Ohne Versionsnummer wird die aktuelle Version (tip) verwendet.
hh@knuth:/Dokumente/mercurial-demo/c2bf$ hg update -r 0
2 files updated, 0 files merged, 1 files removed, 0 files unresolved
hh@knuth:/Dokumente/mercurial-demo/c2bf$ head -6 test.sh
#!/bin/bash
BFI=egobfi16
Test 1
echo -n "Test 1: "
./wrapper/c2bf cc/tests/test1.c
hh@knuth:/Dokumente/mercurial-demo/c2bf$ hg up -r 1
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
hh@knuth:/Dokumente/mercurial-demo/c2bf$ head -6 test.sh
#!/bin/bash
run tests with c2bf
BFI=egobfi16
Test 1
echo -n "Test 1: "
hh@knuth:/Dokumente/mercurial-demo/c2bf$ hg up
2 files updated, 0 files merged, 1 files removed, 0 files unresolved
hh@knuth:/Dokumente/mercurial-demo/c2bf$ head -6 test.sh
#!/bin/bash
run tests with c2bf
BFI=egobfi16
Test 1
hh@knuth:~/Dokumente/mercurial-demo/c2bf$
Übrigens zeigt das Kommando head die mit -[zahl] angegeben Anzahl von Zeilen an (in unserem Beispiel immer 6). Das Kommando hat wie auch vim nichts mit Mercurial zu tun.
In einem weiteren Artikel werde ich zeigen, wie man zusätzlich ein zentrales Repository für ein Team (oder für Abgaben :-)) verwenden kann.
In Zukunft sollten Sie folgendermaßen an Ihren Aufgaben arbeiten:
- Bearbeite einen Punkt der Aufgabe (Mache ein paar Änderungen)
- Schau, ob sie funktionieren
- Funktionieren sie, dann hg commit
- Andernfalls hg revert --all
- GOTO 1
Abgegeben wird dann das Repository, also das Verzeichnis .hg, in einer komprimierten Datei:
tar -czf [jjjj_ N_bhif_aufgabe_N_ _name_vorname_].tgz .hg.
jjjj
Die Jahreszahl des Schuljahresbeginns. Für das Schuljahr 2012/13 also 2012.
N
Bei der Klasse, der Jahrgang (also 2bhif, 3bhif) und bei der Aufgabe die Aufgabennummer (aufgabe1, aufgabe2...).
name_vorname
Ihr Name und Vorname in Kleinbuchstaben sowie ohne Umlaute, scharfes s (ß) und Akzente.
Beispiel:
tar -czf 2012_3bhif_aufgabe2_mayer_juergen.tgz .hg
Wir evaluieren gerade ein paar Möglichkeiten für ein zentrales Repository für die Abgabe. Dann braucht man keine Mails mehr schicken. Details folgen...
Weitere Informationen
- mercurial.selenic.com/wiki/GermanTutorial (deutsch)
- Mercurial Quick Reference Cards and Cheat Sheets (englisch)
- mercurial.selenic.com/ (englisch)
- mercurial.selenic.com/wiki/GermanUnderstandingMercurial (deutsch)
- de.wikipedia.org/wiki/Versionsverwaltung#Verteilte_Versionsverwaltung (deutsch)
- hginit.com (englisches Tutorial, sehr zu empfehlen. Einige Ideen habe ich sinngemäß in diesen Beitrag übernommen)
Labels: allgemeines, hg, mercurial

