Aufgabe und Prinzip einer Versionsverwaltung
Geschichtsschreibung
Git ist eine Versionskontrolle. Eine Versionskontrolle ermöglicht es, Snapshots von Dateizuständen zu sichern und diese alten Versionen wieder zurückholen zu können. Dazu speichern die meisten Versionsverwaltungen die Unterschiede zwischen den Versionen, die in der Regel kleiner sind als eine komplette neue Version der Datei. Darum sind Versionsverwaltungen besonders effizient bei reinen Textdateien wie Programmquelltexten, HTML- oder XML-Dateien, LaTeX-Dokumenten und anderen rohen Textdateien.Die Möglichkeit, die Unterschiede zwischen den Versionen ermitteln zu können, entfallen bei binären Dateien wie Musik, Bildern, aber auch Textverarbeitungsdokumenten wie beispielsweise Word-Dateien. Darum sind Versionsverwaltungen kein idealer Ort, um Binärdaten zu verwalten.
Gemeinschaftspflege
Besonders nützlich ist eine Versionsverwaltung, wenn mehrere Programmierer an einem gemeinsamen Projekt arbeiten. Die Versionsverwaltung verwaltet den gemeinsamen Stand und kann nicht nur die Historie verwalten, sondern auch nachvollziehen, wer welche Änderungen gemacht hat.Startschuss
Ein Projekt wird in einem Repository verwaltet. Soll es ein Gemeinschaftsprojekt werden, wird zunächst ein zentrales Repository angelegt und jeder Entwickler zieht sich davon eine Kopie, ein sogenanntes Clone. Bei git hat also jeder Arbeitsplatz eine eigene Versionsverwaltung, die mit dem zentralen Repository synchronisiert werden kann.Anlegen eines lokalen Repository
Sie müssen aber nicht zwingend mit einem zentralen Repository arbeiten. Sie können mit dem Befehl git init jederzeit ein lokales Repository erzeugen.$ cd src/java/adr $ git init Initialisierte leeres Git-Repository in /home/arnold/src/java/adr/.git/Damit existiert ein lokales Repository. Ein Verzeichnis, das unter einer Versionskontrolle von Git steht, enthält ein lokales Verzeichnis namens .git. Darin werden die Historien verwaltet.
Sollte es aus irgendeinem Grund erforderlich sein, dass Repository wieder zu entfernen, kann dies einfach durch Löschen des Verzeichnisses .git erreicht werden.
$ rm -rf .git
Clone eines zentralen Repositories
Wenn Sie mit einem zentralen Repository arbeiten, muss irgendjemand zunächst auf dem zentralen Server ein Repository mit git init angelegen. Das ist oft nicht so augenfällig, weil die Initialisierung des Repository unter den grafischen Oberflächen von GitLab oder GitHub beim Klick auf einen Button erfolgt, der ein Repository anlegt.Um sich an einem zentralen Repository zu beteiligen, erzeugt man einen Clone zu erzeugen. Dazu benötigt man die URL des Repositories, also die Adresse, über die es zu erreichen ist.
- Ist das zentrale Repository auf einem zentralen Netzwerklaufwerk oder auf einem externen Laufwerk, so kann der Pfad angegeben werden. Zur Verdeutlichung kann das Protokoll file:// vorangestellt werden. Diese Variante sollte man in Zeiten von Ransom-Viren nicht wählen.
- Erfolgt der Zugriff über HTTP, wird http:// oder https:// zur Kennzeichnung vorangestellt.
- Für die Mitarbeit an einem Projekt wird typischerweise SSH verwendet. Die URL ist meist der Form user@server:RepositoryPfad. Manchmal wird auch ssh:// vorangestellt. In diesem Fall muss ein asymetrischer Schlüssel erzeugt werden und der public key auf dem Git-Server hinterlegt werden.
git clone /pfad/projekt git clone git@server:projekt git clone http://server/projektEs entsteht anschließend ein vollwertiges, lokales Repository, auf dem Sie völlig unabhängig vom zentralen Repository arbeiten können, bis Sie später einmal synchronisieren wollen.
Das Ursprungs-Repository kann von Git über den Namen origin angesprochen werden.
Einrichten der Umgebung
Wenn Sie mit einem zentralen Repository arbeiten, ist Ihre Identität wichtig. Dazu konfigurieren Sie mindestens Ihren Namen und Ihre E-Mail-Adresse für die Git-Zugriffe.git config --global user.name "Ihr Name" git config --global user.email ihre@emailadresse.de
Erzeugen eines Schlüsselpaares für SSH
Falls Sie das Protokoll SSH verwenden, benötigen Sie auch einen SSH-Key. Dazu rufen Sie in der Shell den Befehl ssh-keygen auf. Wenn Sie alle Rückfragen mit einer leeren Zeile quittieren, befindet sich der private Schlüssel in der Datei id_rsa im Unterverzeichnis .ssh des Benutzerverzeichnisses. Dieser sollte dort auch bleiben. Die Datei id_rsa.pub ist öffentlich, kann verteilt werden und sollte auch dem Git-Server mitgegeben werden.Dateizustände
Die Dateien im Arbeitsverzeichnis haben zunächst nichts mit dem Repository zu tun. Sie müssen explizit in einen Status gebracht werden, dass sie übernommen werden.In der Anzeige der Dateien durch git status erscheinen sie als unversionierte Dateien.
Changed
Änderungen an Dateien, auch solchen, die bereits im Repository stehen, werden zwar von Git bemerkt, führen aber nicht dazu, dass die Änderungen beim nächsten Abgleich automatisch in das Repository übernommen werden. Der Status der Datei ist changed.Sollen die Änderungen in das Repository gelangen, müssen sie zunächst in die Staged Area geschafft werden.
Staged Area
Eine Datei muss vor der Übernahme in das Repository mit dem Befehl git add in die Staged Area aufgenommen werden.$ git add copyright.txtDamit ist sie nur für Übernahme markiert.
$ git statusDer Status-Befehl gibt Ihnen Auskunft über den Stand Ihrer Dateien im Arbeitsverzeichnis. Dateien, die hier nicht auftauchen, fühlen sich bereits im Repository wohl und brauchen keine Pflege. Es erscheinen alle Dateien, die geändert wurden oder sich in der Staged Area befinden.
Übernahme ins lokale Repository: Commit
Alle Dateien der Staged Area werden mit dem Befehl git commit in das lokale Repository übernommen. Für diese Übernahme erwartet das System einen Kommentar, der in einem Editor eingegeben werden muss. Alternativ kann er auch mit der Option -m gleich im Commit-Befehl eingebaut werden.$ git commit -m "Copyright für ein wichtiges Programm" [master (Basis-Commit) da2828f] Copyright für ein wichtiges Programm 1 file changed, 2 insertions(+) create mode 100644 copyright.txt $
Sie können nach dem Status Ihres Arbeitsverzeichnis fragen:
$ git status Auf Branch master nichts zu committen, Arbeitsverzeichnis unverändert $Wird nach dem Commit an der Datei geändert, wird dies zwar von git bemerkt, führt aber erst dann zur Übernahme beim nächsten Commit, wenn die Datei mit einem erneuten Befehl git add in den Zustand staged gebracht wird. Das sorgt dafür, dass keine unfertigen Zwischenstände versehentlich ins Repository geraten.
Übersicht der Dateizustände
Dadurch ergeben sich für die in einem Arbeitsverzeichnis stehenden Dateien verschiedene möglichen Dateizustände. Welchen Zustand die Dateien im aktuellen Verzeichnis haben, ermitteln Sie mit dem Befehl git status.- modified
- Die Datei wurde im Arbeitsverzeichnis gegenüber dem Zustand im lokalen Git-Repository geändert. Diese Änderungen bewirken nicht automatisch eine Übernahme in das Repository.
- staged
-
Erst wenn die lokale Änderung in die Versionskontrolle einfließen soll,
wird die Datei datei.txt mit dem folgenden Befehl
für die Übernahme vorbereitet.
git add datei
Damit befindet sich die Datei in dem staged Zustand. Nur Dateiänderungen, die so angemeldet sind, werden beim Befehl git commit in das lokale Git-Repository übernommen. - committed
- Durch den Befehl git commit werden alle Dateien, die sich im staged-Zustand befinden, in die lokale Versionskontrolle übernommen. Dazu wird ein Commit-Kommentar eingefordert, der mit dem Commit gespeichert wird.
Protokolle
Der Befehl git log zeigt die Liste der Commits an. Dabei werden folgende Informationen angezeigt:- die Commit-ID. Daran können Sie eine Version identifizieren.
- den beim Commit angegebenen Kommentar. Wer sich die Liste anschaut, kann viel darüber lernen, wie gelungene Kommentare aussehen. Sie sollten einerseits knapp sein, damit sie idealerweise in eine Zeile passen und auf der anderen Seite den Status der Änderung gut beschreiben.
- der Autor des Commits.
Der Befehl git log erlaubt weitere Optionen.
- Mit der Option -p werden die vom Commit betroffenen Dateien angezeigt.
- Die Option -2 zeigt die letzten beiden Commits.
Rückzieher
Mit dem Befehl git reset können Sie eine Datei aus dem Zustand staged wieder zurückholen, damit sie nicht beim nächsten Commit-Befehl mitgenommen wird.Sollen eine Datei aus dem Zustand staged wieder in den Zustand changed gebracht werden, wird der folgende Befehl eingestetzt:
$ git reset copyright.txtLokale Änderungen können auf den Repository-Stand durch den Befehl git checkout zurückgesetzt werden. Dazu muss der Dateiname als Argument angegeben werden.
$ git checkout copyright.txtSoll der Stand eines entfernten Repository alle lokalen Änderungen überschreiben, verwendet man die folgenden Befehle:
git fetch origin git reset --hard origin/master
Datei entfernen und umbenennen
Eine Datei wird aus dem Repository mit dem Befehl git rm entfernt.$ git rm copyright.txtIm Anschluss wurde die Datei copyright.txt aus dem Arbeitsbereich gelöscht und der Löschvorgang in die Staged Area übernommen. Erst mit einem Commit wird die Datei auch aus dem Repository-Stand entfernt. Analog wird für das Umbenennen der Befehl git mv verwendet:
$ git mv datei.txt neuname.txt
Abgestempelt: Tag
Mit einem Tag können Stände markiert werden. Gern werden dafür Versionsnummern verwendet. Um einen Stand mit einem Tag zu versehen, verwendet man den folgenden Befehl:$ git tag v1.4 -m 'my version 1.4'Mit dem Befehl git tag ohne weitere Parameter erhält man eine Liste aller Tags in alphabetischer Reihenfolge.
Sie können einen alten Commit mit einem Tag versehen, indem Sie die Commit-ID hinten anhängen.
$ git tag v1.6 4b491290521630bdddb4280b20fddc18b6b4cc40Tags wandern nur dann vom lokalen in das zentrale Repository, wenn das Tag als Argument angegeben wird.
$ git push origin v1.5Sollen alle Tags übernommen werden, wird dem Push-Befehl als Option --tags mitgegeben.
Abzweigung: Branch
Mit einem Branch wird eine Weiterentwicklung des Projekts angelegt, die zunächst unabhängig vom Hauptstrang verfolgt wird. Erst wenn die Weiterentwicklung produktreif ist, wird sie wieder in den Hauptstrang integriert. So können Erweiterungen entwickelt werden und dennoch jederzeit stabile Versionen an den Kunden ausgeliefert werden.Der Hauptzweig trägt den Namen master. Der aktuelle Branch wird durch den Namen HEAD bezeichnet und zeigt anfangs auf master.
Der folgende Befehl erzeugt einen Branch namens testbranch.
$ git branch testbranchEine Übersicht über alle angelegten Branches zeigt der Befehl git branch ohne Argumente.
Umsetzen des Branches
Um mit dem Branch normal arbeiten zu können, wird HEAD auf diesen Branch gesetzt.$ git checkout testbranchSie können das Erzeugen und Wechseln zu einem Branch auch zusammenfassen, indem Sie dem Checkout-Befehl die Option -b hinzufügen.
$ git checkout -b testbranchDieser Befehl erzeugt den Brach testbranch und wechselt sofort dorthin.
Nun wirken Commits auf den Branch testbranch, während der Hauptzweig master unverändert bleibt. Soll wieder auf den Hauptzweig verwiesen werden, wird HEAD wieder auf den Zweig master gesetzt.
$ git checkout master
Familienzusammenführung
Um den Zweig testbranch in den Hauptzweig einzufädeln, wird zunächst der Hauptzweig zum HEAD gesetzt und anschließend der Branch mit dem Befehl git merge eingepflegt.git checkout master git merge testbranchWar eine Zusammenführung nicht konfliktfrei möglich, liefert der Merge-Befehl entsprechende Fehlermeldungen. Der Befehl git status zeigt den Konflikt auf.
Für die Konfliktbereinigung kann der Befehl git mergetool aufgerufen werden.
Abknicken
Hat die Zusammenführung geklappt, kann der Branch testbranch wieder gelöscht werden.git branch -d testbranch
Verbindung zum zentralen Repository
Clone des zentralen Repositories
Wenn ein zentrales Repository besteht, holt sich jeder Arbeitsplatz einen Clone davon. Dadurch entsteht eine Beziehung zwischen den beiden. Das Ursprungs-Repository wird danach automatisch als origin angesprochen.
git clone git@gitserver:meinRepositoryDer Entwickler kann sein lokales Repository verwenden, ohne mit dem entfernten Repository Kontakt zu haben. Mit dem Befehl git push wird der aktuelle Stand im lokalen Repository auf den zentralen Server geschrieben werden.
git pushUm Änderungen der Kollegen vom zentralen Repository in das lokale Repository zu übernehmen wird der Befehl git pull aufgerufen. Es empfielt sich, dies häufig zu tun, um die Stände nicht zu sehr auseinander laufen zu lassen.
git pullBei beiden Befehlen wird Git als remote Repository origin verwenden, so lange ihm keine weiteren Angaben als Argument geliefert werden.
Bezug zu einem anderen Repository definieren
Mit dem Befehl git remote add wird die Verbindung zu einem entfernten Repository definiert. Das entfernte Repository erhält einen Namen, hier origin. Sie können mit git remove namen die Definition wieder entfernen.$ git remote add origin git@debian:/var/git/testprojektNun werden mit dem Befehl push über den Namen (oder alternativ direkt über die URL) in das Remote Repository geschoben werden.
$ git push origin master git@debian's password: Zähle Objekte: 9, Fertig. Delta compression using up to 8 threads. Komprimiere Objekte: 100% (9/9), Fertig. Schreibe Objekte: 100% (9/9), 6.50 KiB | 0 bytes/s, Fertig. Total 9 (delta 0), reused 0 (delta 0) To git@debian:/var/git/testprojekt * [new branch] master -> master