Geschichte schreiben (add, commit)

Nachdem wir Git eingerichtet haben und die nötigsten Optionen gesetzt sind, wollen wir nun versuchen die Grundlagen der Git-Nutzung mit einem Beispielprojekt zu lernen.

Dazu sollten wir zunächst ein paar Grundbegriffe über die Benutzung klären.

Habt ihr ein Projekt, liegt es höchstwahrscheinlich als Verzeichnis vor, indem einige Dateien und unterverzeichnisse liegen. Wird dieses Verzeichnis mit einem Versionsverwaltungssystem verwaltet, nennt man es „Arbeitskopie“.

Eine Arbeitskopie ist - wie der Name schon sagt - eine Kopie, mit der ihr Arbeiten könnt. Dort könnt ihr Dateien ändern, hinzufügen oder löschen, ihr könnt die Quellcodedateien zum Kompilieren verwenden oder auch sonst alles machen.

In einem verteilten Versionsverwaltungssystem wie Git 1) es ist ist, besitzt jede Arbeitskopie auch ein sogenanntes „Repository“. Dies ist bei zentralen Versionsverwaltungssystemen, wie CVS und Subversion nicht so: das Repository liegt auf einem entfernten Server.

Repository ist Englisch für Lagerstätte oder Aufbewahrungsort, und das wird dort auch gemacht: alle Änderungen und Dateien die ihr tätigt werden dort gespeichert und aufbewahrt. In diesem Tutorial werde ich dafür das englische Wort „Repository“ verwenden.

Repository Anlegen

Um also unser Projekt zu verfolgen, müssen wir zuerst ein Repository anlegen. Dazu legen wir ein Verzeichnis an, und wechseln dort hinein

mkdir helloworld
cd helloworld


Anschließend erstellen - oder besser gesagt initiieren - wir ein Git-Repository:

git init


Und schon ist es erstellt! Überprüfen könnt ihr das, indem ihr mit 'ls -a' alle Unterverzeichnisse anzeigen lasst. Das Repository ist das .git-Unterverzeichnis.

Neue Dateien hinzufügen

Jetzt wollen wir mit der Arbeit beginnen. Dazu werden wir das typische „Hello World“- Programm schreiben, und es anschließend eintragen. Ihr könnt die Datei entweder mit einem Editor erstellen, oder ihr kopiert einfach das Folgende in eure Konsole:

cat > helloworld.c << EOF
#include <stdio.h>

int main()
{
    printf ("Hello World!\n");

    return 0;
}

EOF


Wollt ihr diese Datei nun eintragen, müsst ihr Git erstmal bekannt geben, dass es eure Datei verfolgen soll. Dies geschieht mit dem Befehl add:

git add helloworld.c


Anschließend müssen wir die Änderungen commiten (das bedeutet Eintragen). Dies geschieht mit dem commit-Befehl:

git commit


Dies startet euren eingestellten Editor, mit dem ihr den Commit beschreiben müsst: schreibt eine Art kleinen Logbucheintrag über eure Änderungen. Diese Nachricht wird gespeichert, und soll als erklärung der Änderung dienen, damit man auch in Zukunft nachvollziehen kann was ihr warum gemacht habt. Haltet euch kurz, bleibt präzise und beschreibt mit so wenig Worten wie möglich was ihr wozu getan habt.

Das Format ist dabei zwar völlig frei Wählbar, es empfiehlt sich allerdings ein bestimmtes Format einzuhalten, damit ihr die Änderungen bequem lesen könnt:

  • Die erste Zeile beschreibt in aller Kürze die Änderung, und darf nicht länger als 50 Zeichen sein.
  • Die zweite Zeile bleibt leer
  • Die darauffolgenden Zeilen könnt ihr frei zur Beschreibung verwenden,

diese sollten aber nicht länger als 76 Zeichen sein.

Für den ersten Commit hat es sich eingebürgert einfach nur „Initial commit“ als Nachricht zu verwenden.

Habt ihr eure Nachricht eingetragen, speichert die offene Datei und schließt den Editor. Als Antwort bekommt ihr nun, welcher Zweig aktualisiert wurde, und eine kleine Zusammenfassung der Änderungen. Bei mir sieht das Beispielsweise so aus:

[master (Basis-Version) 0b78177] Initial commit
 1 Datei geändert, 9 Zeilen hinzugefügt(+)
 create mode 100644 helloworld.c


Gratulation! Damit habt ihr euren ersten Commit getätigt!

Da das jetzt so schön war, fügen wir noch eine Datei names Makefile hinzu:

.PHONY: clean
all: helloworld

helloworld: helloworld.c

clean:
	$(RM) helloworld


git add Makefile
git commit -m "Makefile hinzugefügt"


Verzeichnisse hinzufügen

Dem add-Befehl könnt ihr auch ganze Verzeichnisse hizufügen:

git add <verzeichnis>/

Das tut aber nicht das was ihr wahrscheinlich denkt: es fügt alle Dateien in diesem Verzeichnis und allen Unterverzeichnisse hinzu, und damit zwar automatisch das angegebene Verzeichnis selbst. Leere Verzeichnisse können allerdings nicht hinzugefügt werden!

Begründet wird das damit dass Git ja ein „Content“-Tracker ist, und Verzeichnisse keine Inhalte sind, sondern nur Organisationsstrukturen.

Wie auch immer, ihr könnt leider keine leeren Verzeichnisse in Git verfolgen. Es gibt allerdings einen Trick, um das zu erreichen: erstellt eine Datei namens .gitignore (siehe unten) in dem Verzeichnis das ihr verfolgen wollt. Dann ist es zwar nicht ganz leer, enthält aber nur eine versteckte, leere Datei.

Dateien ändern

Nun werden wir versuchen, eine vorhandene Datei zu Ändern, und diese Änderungen einzutragen.

Vorher möchte ich allerdings eure Aufmerksamkeit auf einen neuen Befehl lenken: der status-Befehl:

git status


Dieser Befehl gibt euch Auskunft über den derzeitigen Status eurer Arbeitskopie: auf welchem Zweig ihr euch befindet, welche Dateien geändert sind, und welche zum Eintragen markiert sind. Kurz: er gibt Auskunft darüber „was gerade abgeht“.

Dementsprechend würde ich euch empfehlen, dass ihr ihn immer dann eingebt, wenn ihr nicht sicher seid in welchen Zustand sich eure Arbeitskopie gerade befindet. Dies wird am Anfang noch öfter nötig sein, mit der Erfahrung bekommt ihr aber ein Gefühl dafür.

Gebt nun diesen Befehl ein, und seht euch die Ausgabe an. Bei mir sieht das so aus:

# Auf Zweig master
nichts zum Eintragen (Arbeitsverzeichnis sauber)


Klar. Wir befinden uns auf dem Zweig „master“ (unser „Haupt“-Zweig), und wir haben seit unserem Letzten Commit nichts geändert (deswegen ist das Arbeitsverzeichnis „sauber“) und auch nichts mit add hinzugefügt (deswegen haben wir „nichts zum Eintragen“).

Jetzt werden wir unser Programm ändern. Das geschieht wie auch immer ihr das normalerweise macht. Sagen wir, wir wollen nun nicht mehr die Welt grüßen, sondern nur proggen.org. Ändert also die 5. Zeile in der Datei helloworld.c und speichert die Datei. Wenn ihr zu faul seid, kopiert einfach folgendes Zauberkommando in eure Kommandozeile:

sed -i -e 's/World!/proggen.org!/g' helloworld.c


So. Nun rufen wir noch einmal git status auf. Die Ausgabe sieht bei mir so aus:

# Auf Zweig master
# Änderungen, die nicht zum Eintragen bereitgestellt sind:
#   (benutze "git add <Datei>..." zur Aktualisierung der Eintragung)
#   (benutze "git checkout -- <Datei>..." um die Änderungen im Arbeitsverzeichnis zu verwerfen)
#
#	geändert:   helloworld.c
#
keine Änderungen zum Eintragen hinzugefügt (benutze "git add" und/oder "git commit -a")


Wir befinden uns immer noch auf dem Zweig „master“, haben aber jetzt Änderungen in unserem Arbeitsverzeichnis. Habt ihr color.ui eingeschalten, wird die Datei helloworld.c rot angezeigt.

Achtung: wenn ihr jetzt commiten würdet, würde das gar nicht gehn, da keine Änderungen bereitgestellt sind! Dies ist ein Unterschied zu anderen Versionsverwaltungssystemen (wie z.B. Subversion), denn dort würden alle Änderungen an bekannten Dateien eingetragen werden.

Nicht so bei Git. Hier müsst ihr die Änderungen zuerst „Bereitstellen“, und zwar mit dem Befehl add. Dieser fügt die Änderungen an einer Datei in die sogenannte „staging Area“ oder kurz „Index“ hinzu.

Wenn ihr den commit-Befehl aufruft, werden immer nur diejenigen Änderungen commitet, die sich im Index befinden. Für Novizen sieht das erstmal wie Mehrarbeit im Vergleich zu SVN aus, ihr werdet diese Funktionsweise aber mit der Zeit zu schätzen lernen!

Nun gut, jetzt tragen wir unsere Änderungen ein:

git add helloworld.c


Sehen wir uns den status an:

git status


Die Ausgabe ist:

# Auf Zweig master
# zum Eintragen bereitgestellte Änderungen:
#   (benutze "git reset HEAD <Datei>..." zum Herausnehmen aus der Bereitstellung)
#
#	geändert:   helloworld.c
#


Wie ihr nun seht, sind die Änderungen die wir gemacht haben „zum Eintragen bereitgestellt“ - die Datei helloworld.c ist nun grün. Man sagt, die Änderungen befinden sich „im Index“. Der „Index“ ist der Zustand der Arbeitskopie, den sie beim nächsten Commit haben soll.

Beachtet, dass wenn ihr helloworld.c jetzt noch einmal bearbeiten würdet, würden die neuen Änderungen nicht eingetragen werden. Wollt ihr die Datei weiter bearbeiten und die Gesamtänderungen commiten, müsst ihr sie nach dem Ändern noch einmal mit add hinzufügen.

Wir könnten jetzt einen Commit tätigen, und die Änderungen würden aufgezeichnet werden. Das machen wir allerdings noch nicht.

Wir sehen uns zuerst nochmal an, was passiert wenn man weitere Änderungen tätigt. Ändern wir die Makefile-Datei zu folgendem:

.PHONY: clean
all: helloworld

helloworld: helloworld.c
	$(CC) $(CFLAGS) -o $@ $<

clean:
$(RM) helloworld


Sehen wir uns den jetzigen Status an:

git status


# Auf Zweig master
# zum Eintragen bereitgestellte Änderungen:
#   (benutze "git reset HEAD <Datei>..." zum Herausnehmen aus der Bereitstellung)
#
#	geändert:   helloworld.c
#
# Änderungen, die nicht zum Eintragen bereitgestellt sind:
#   (benutze "git add <Datei>..." zur Aktualisierung der Eintragung)
#   (benutze "git checkout -- <Datei>..." um die Änderungen im Arbeitsverzeichnis zu verwerfen)
#
#	geändert:   Makefile
#


Jetzt sehen wir, dass helloworld.c bereitgestellt (im Index) ist, und das Makefile nicht. Würdet ihr jetzt den Commit tätigen, würde nur die helloworld.c-Datei eingetragen werden. Das seht ihr auch an der Farbe: helloworld.c ist grün und Makefile ist rot.

Wir können uns die Änderungen auch detailliert anzeigen lassen. Wollt ihr euch die Änderungen ansehen, die beim nächsten commit eingetragen werden, benutzt folgenden Befehl:

git diff --cached


Wollt ihr die Änderungen zwischen dem Index und dem jetzigen Zustand der Arbeitskopie anzeigen (also alle noch nicht bereitgestellten Änderungen), benutzt Folgendes:

git diff


Wollt ihr die gesamten Änderungen, die seit dem letzten Commit geschehen sind anzeigen lassen, benutzt

git diff HEAD


mit diesen Befehlen wird das jeweilige diff in einem Pager angezeigt. Die Navigation in der Ausgabe könnt ihr hier nachlesen: In der Ausgabe scrollen.

Näheres zu diff und HEAD findet ihr im nächsten Kapitel.

Bevor man die Änderungen tatsächlich commitet, sollte man stets überprüfen das nur die richtigen Änderungen, die ihr eintragen wollt auch tatsächlich bereitgestellt sind. Überprüft mit 'git status', ob auch die richtigen Dateien markiert sind, und eventuell mit 'git diff --cached' was eingetragen wird. Wenn ihr euch vergewissert habt, dass alles in Ordnung ist, könnt ihr weitermachen.

Stellen wir nun alle Änderungen bereit und erstellen den Commit:

git add Makefile
git commit


Als Commit-Nachricht geben wir „Grüße nur proggen.org statt der Welt“ ein.

Überprüft ihr jetzt noch einmal den Status, sollte das Arbeitsverzeichnis wieder als „sauber“ angezeigt werden.

Dateien löschen und Umbenennen

Selbstverständlich kann man in Git auch Dateien löschen. Dies geschieht mit dem Befehl rm:

git rm <datei>


Man kann auch ganze Verzeichnisse löschen, dazu übergibt man den Schalter '-r':

git rm -r <verzeichnis>


Das werden wir jetzt an unserem Beispielprojekt üben: zunächst erstellen wir eine Kopie der Datei helloworld.c, und löschen dann die Ursprungsdatei:

cp helloworld.c hello.c
git rm helloworld.c


Ein git status zeigt nun folgendes an:

# Auf Zweig master
# zum Eintragen bereitgestellte Änderungen:
#   (benutze "git reset HEAD <Datei>..." zum Herausnehmen aus der Bereitstellung)
#
#	gelöscht:    helloworld.c
#
# Unverfolgte Dateien:
#   (benutze "git add <Datei>..." zum Einfügen in die Eintragung)
#
#	hello.c


Das Löschen der Datei ist nun bereitgestellt (im Index), und mit ls könnt ihr Überprüfen, dass die Datei auch von eurem Dateisystem gelöscht ist.

Jetzt werden wir die Kopie der gelöschten Datei wieder zu unserem Projekt hinzufügen, das geschieht in der gewohnten Weise mit

git add hello.c


Ein 'git status' zeigt nun folgendes:

# Auf Zweig master
# zum Eintragen bereitgestellte Änderungen:
#   (benutze "git reset HEAD <Datei>..." zum Herausnehmen aus der Bereitstellung)
#
#	umbenannt:    helloworld.c -> hello.c
#


Wie ihr seht, hat Git, obwohl wir die Datei kopiert, das Original gelöscht und die Kopie hinzugefügt haben die Operation als „Umbennen“ erkannt.

Tatsächlich ist es so, dass es unter Git kein richtiges „Umbennen“ gibt! Es gibt zwar den mv-Befehl der auch funktioniert wie man es erwarten würde, dieser tut aber nichts anderes als wir gerade gemacht haben - und zwar die alte Datei löschen und die gleiche Datei mit anderem Namen hinzufügen.

Das Erkennen ob es sich dabei um Umbennenen handelt, übernimmt Git. Das mag auf den ersten Blick zwar Sinnfrei erscheinen, aber: in der Philosophie von Git zählt nur eines: der Inhalt. Für Git bewegen sich nur Codezeilen, wie die dazugehörigen Dateien heißen oder wie diese auf dem Dateisystem repräsentiert sind ist Git egal. Das ermöglicht vielen Git-Befehlen so effektiv wie möglich zu sein.

Um unsere Änderungen abzuschließen, sollten wir noch eine kleinigkeit im Makefile ändern: und zwar alle vorkomnisse von „helloworld“ auf „hello“ zu ändern. Das geht mit folgendem Zauberkommando:

sed -i -e 's/helloworld/hello/g' Makefile


Diese Änderungen stellen wir ebenfalls bereit:

git add Makefile


Bevor wir commiten, sollten wir uns zumindest mit 'git status' ansehen, ob alle Änderungen so eingetragen werden, wie wir uns das gedacht haben. Eventuell könnt ihr die Änderungen mit 'git diff --cached' überprüfen. Erst wenn ihr sicher seid, dass alles in Ordnung ist, tragen wir die Änderungen ein:

git commit


Als Nachricht geben wir dabei „helloworld.c umbenannt“ ein.

< Zurück | Index | Weiter >


Fortgeschrittene Themen

Damit würde ich dieses Kapitel gerne beenden, denn das Wichtigste dazu wie man Geschichte schreibt und einträgt ist gesagt. Allerdings gäbe es noch einige weitere interessante Punkte, die ich gerne ansprechen würde. Diese werden zwar nützlich sein, sind aber nicht zwingend für die Benutzung von Git erforderlich.

Aus diesem Grund werden diese Punkte in dem Abschnitt „Fortgeschrittene Themen“ angesprochen. Wenn ihr mit dem bisher gelernten überfordert sein, rate ich euch diesen Teil zu überspringen und später darauf zurückzukommen. Ist euer Kopf noch frisch, könnt ihr ruhig weitermachen.

Abkürzungen

Ist die Commit-Nachricht kurz, könnt ihr sie auch direkt als Kommandozeilenparameter angeben. Dazu überreicht den Parameter --message oder -m und danach die Nachricht in Anführungszeichen:

git commit -m "Initial commit"


Damit spart ihr euch, dass der Editor aufgerufen wird.

Mit 'git add -u' könnt ihr alle Änderungen an jeder Datei, die Git bereits kennt in den Index stellen.

Außerdem könnt alle Änderungen an jeder Datei, die Git bereits kennt eintragen lassen und damit das manuelle eintragen in den Index umgehen. Dies geschieht mit dem Schalter -a. Ihr könnt ihn auch zusammen mit -m verwenden:

git commit -am "Einiges geändert"


Dazu ein kleiner Tip für euch: FINGER WEG VON DIESER OPTION! Obwohl das quasi das „Standardverhalten“ von SVN wäre, würde ich euch raten das nicht zu tun. Es ist (mir selbst, aber auch Anderen) schon oft genug passiert, dass deswegen Dateien fehlen, unbeabsichtigt hinzugefügt, oder die falschen Änderungen eingetragen wurden. Tut euch selbst einen Gefallen, und lasst es.

Dateien ignorieren - .gitignore und .git/info/exclude

Jedes mal, wenn ihr git status aufruft, werden alle Dateien, die Git nicht bekannt sind als „nicht verfolgt“ („untracked“) angezeigt. Dies stellt eigentlich kein Problem dar, denn solange ihr diese Dateien nicht manuell hinzufügt, wird es keine Probleme geben.

Sind das allerdings viele Dateien, die öfters auftauchen und die die Ausgabe von git status nicht zumüllen sollen, gibt es eine Möglichkeit diese dauerhaft auszublenden.

Das ist zum Beispiel für temporäre Dateien des Bau-Systems, für kompilierte Dateien oder für Backupdateien eures Editors nützlich.

Diese Dateien und Ordner könnt ihr nach einem bestimmten Muster entweder in die Datei .gitignore oder in die Datei .git/info/exclude eintragen. Wohin ihr eure ignorierten Dateien eintragt ist eigentlich egal, allerdings wird .git/info/exclude für „private“ Dateien (also Dateien, die nur euren eigenen Arbeitsfluss betreffen) und .gitignore für „öffentliche“ ignorierte Dateien (also Dateien, die bei allen Entwicklern ignoriert werden sollten) verwendet. Dementsprechend muss .gitignore (im Gegensatz zu .git/info/exclude) auch zur Geschichte hinzugefügt und eingetragen werden.

Das Muster für die Erkennung der ingorierten Dateien ist relativ einfach:

  • Leere Zeilen werden ignoriert
  • Zeilen, die mit einem # beginnen, werden ignoriert
  • Zeilen, die kein '/' (Slash) enthalten, enthalten ein Shell-Glob-Muster, das ihr auch auf der Kommandozeile verwenden könntet, und zwar relativ zum Verzeichnis der .gitignore-Datei (oder vom Wurzelverzeichnis der Arbeitskopie, wenn das Muster nicht in einer .gitignore-Datei steht).
  • Alle anderen Zeilen enthalten ein Shell-Glob-Muster, in dem der Wildcard nicht auf '/' (Slash) passt. Beispielsweise passt das Muster „Documentation/*.html“ auf „Documentation/git.html“, aber nicht auf „Documentation/ppc/ppc.html“ oder „tools/perf/Documentation/perf.html“.
  • Muster, die mit einem Slash ('/') enden, passen nur auf Verzeichnisse
  • Ein Slash ('/') zu beginn passt auf den Beginn eines Pfadnamens. Zum Beispiel passt „/*.c“ auf „cat-file.c“ aber nicht auf „mozilla-sha1/sha1.c“.
  • Zeilen, die mit einem Rufzeichen (!) beginnen kehren die Wirkung des darauffolgenden Ausdrucks um (jede Datei, die nicht auf den Ausdruck passt wird ausgeschlossen)

Die Datei .gitignore könnt ihr in jedes Verzeichnis platzieren. Dabei werden bestimmte Muster (siehe oben) relativ zum Pfad der der .gitignore-Datei ignoriert.

Diese Datei könntet ihr vielleicht auch dazu nutzen, um „leere“ Verzeichnisse in Git zu erzwingen. Legt dazu einfach in dem leeren Verzeichnis die .gitignore-Datei an, fügt diese hinzu und commitet die Änderung. Selbstverständlich ist das Verzeichnis dabei nicht tatsächlich Leer, sondern enthält nur eine einzige versteckte Datei.

Wir werden nun in unserem Projekt alle Dateien ignorieren, die aus dem Quellcode gebaut werden können:

printf 'hello\n' >> .gitignore
printf '*.o\n' >> .gitignore
git add .gitignore
git commit -m ".gitignore hinzugefügt"


Erzeugt euer Editor noch gerne Backupdateien, die z.B. mit einer Tilde ('~') enden, sollten diese ebenfalls ignoriert werden. Dieses Muster kommt nach .git/info/exclude:

printf '*~\n' >> .git/info/exclude


Für die Details und eine vielleicht klarere Erklärung darüber wie Git Dateien ignoriert, seht euch bitte die Git-Hilfe zu .gitnigore mit git help ignore an.

Stückweises hinzufügen zum Index

Der Sinn des Index' besteht unter anderem darin, dass man an einer Arbeitskopie mehrere Änderungen hintereinander ausführen kann, und diese dann in der Geschichte als „schrittweise“ Änderungen, in mehreren Commits darstellen kann.

Mit dem bisher Gelernten kann man nur ganze Dateien zum Index hinzufügen, allerdings könnte es sein dass man an einer Datei mehrere Änderungen gemacht hat, die man gerne in verschiedenen Commits hätte.

Für diesen Fall bietet Git eine Lösung an: man kann die Änderung an einer oder mehreren Dateien „stückweise“ hinzufügen. Ein „Stück“ ist in diesem Fall ein sogenannter Hunk, ein Teil eines Patches.

Seht ihr euch nämlich ein Diff an, werdet ihr bemerken, dass ein Patch aus mehreren Bereichen besteht: den hinzugefügten Zeilen, den entfernten Zeilen und dem „Kontext“, der um die geänderten Zeilen ist. Einen solchen Bereich bezeichnet man als Hunk.

Näheres zum Format von Patches findet ihr in der Wiki-Seite von Diff/Patch.

Mit Git hat man die Möglichkeit, die Änderungen an einer Datei in diesen „Hunks“ in den Index zu stellen, und dazu übergebt ihr git add den Schalter -p oder --patch:

git add -p <Pfade> ...


Tut ihr das, kommt ihr in eine Art „interaktiven Hinzufügemodus“, bei dem euch jeder Hunk gezeigt wird und ihr entscheiden müsst, ob ihr ihn bereitstellen wollt oder nicht.

Mit y könnt ihr ihn hinzufügen, mit n ablehnen und mit q das Hinzufügen beenden.

Ihr könnt außerdem den Hunk bis zu einer gewissen Mindestgröße weiter Teilen, und zwar mit der Taste s. Wollt ihr einen Hunk kleiner als diese Mindestgröße bereitstellen, müsst ihr den Hunk manuell eingben (wählt dazu die Option e). Ich muss allerdings zugeben, dass ich es noch nie geschafft habe, einen solchen manuellen Hunk ordnungsgemäß hinzuzufügen 2).

Dabei gibt es noch weitere Optionen, die ihr mit der Taste ? abfragen könnt.

Seid ihr mit dem stückweisen Hinzufügen fertig (indem ihr entweder alle Hunks abgearbeitet habt oder die Abfrage vorzeitig verlassen habt), dann sollten bei einem git status die Dateien doppelt angezeigt werden (außer ihr habt keinen oder alle Hunks angenommen): als Dateien mit bereitgestellten und mit nicht bereitgestellten Änderungen - klar, ihr habt ja nur einen Teil der Änderungen bereitgestellt und den anderen nicht.

< Zurück | Index | Weiter >


Hat dir dieser Artikel geholfen? Wenn nicht oder wenn du Verbesserungs- bzw. Erweiterungsvorschläge hast, dann schreib das bitte einfach auf die Diskussionsseite.

1)
und Mercurial und Bazaar
2)
wenn ihr es geschafft habt, bitte meldet euch im Diskussionsthread!