-
1. Erste Schritte
-
2. Git Grundlagen
-
3. Git Branching
- 3.1 Branches auf einen Blick
- 3.2 Einfaches Branching und Merging
- 3.3 Branch-Management
- 3.4 Branching-Workflows
- 3.5 Remote-Branches
- 3.6 Rebasing
- 3.7 Zusammenfassung
-
4. Git auf dem Server
- 4.1 Die Protokolle
- 4.2 Git auf einem Server einrichten
- 4.3 Erstellung eines SSH-Public-Keys
- 4.4 Einrichten des Servers
- 4.5 Git-Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Von Drittanbietern gehostete Optionen
- 4.10 Zusammenfassung
-
5. Verteiltes Git
-
6. GitHub
-
7. Git Tools
- 7.1 Revisions-Auswahl
- 7.2 Interaktives Stagen
- 7.3 Stashen und Bereinigen
- 7.4 Deine Arbeit signieren
- 7.5 Suchen
- 7.6 Den Verlauf umschreiben
- 7.7 Reset entzaubert
- 7.8 Fortgeschrittenes Merging
- 7.9 Rerere
- 7.10 Debuggen mit Git
- 7.11 Submodule
- 7.12 Bundling
- 7.13 Replace (Ersetzen)
- 7.14 Anmeldeinformationen speichern
- 7.15 Zusammenfassung
-
8. Git einrichten
- 8.1 Git Konfiguration
- 8.2 Git-Attribute
- 8.3 Git Hooks
- 8.4 Beispiel für Git-forcierte Regeln
- 8.5 Zusammenfassung
-
9. Git und andere VCS-Systeme
- 9.1 Git als Client
- 9.2 Migration zu Git
- 9.3 Zusammenfassung
-
10. Git Interna
-
A1. Anhang A: Git in anderen Umgebungen
- A1.1 Grafische Schnittstellen
- A1.2 Git in Visual Studio
- A1.3 Git in Visual Studio Code
- A1.4 Git in IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git in Sublime Text
- A1.6 Git in Bash
- A1.7 Git in Zsh
- A1.8 Git in PowerShell
- A1.9 Zusammenfassung
-
A2. Anhang B: Git in deine Anwendungen einbetten
- A2.1 Die Git-Kommandozeile
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Anhang C: Git Kommandos
- A3.1 Setup und Konfiguration
- A3.2 Projekte importieren und erstellen
- A3.3 Einfache Snapshot-Funktionen
- A3.4 Branching und Merging
- A3.5 Projekte gemeinsam nutzen und aktualisieren
- A3.6 Kontrollieren und Vergleichen
- A3.7 Debugging
- A3.8 Patchen bzw. Fehlerkorrektur
- A3.9 E-mails
- A3.10 Externe Systeme
- A3.11 Administration
- A3.12 Basisbefehle
4.1 Git auf dem Server - Die Protokolle
An dieser Stelle solltest du in der Lage sein, die meisten der täglichen Aufgaben zu erledigen, für die du Git verwenden wirst. Um jedoch in Git mit Anderen zusammenarbeiten zu können, benötigst du ein externes Git-Repository. Obwohl du, technisch gesehen, Änderungen in und aus den Repositorys deiner Mitstreiter schieben kannst, ist das nicht empfehlenswert, da das ziemlich leicht zu Verwirrung führen kann, wenn du nicht sehr vorsichtig bist. Darüber hinaus ist es vorteilhaft, dass deine Mitstreiter auch dann auf das Repository zugreifen können, wenn dein Computer offline ist – ein zuverlässigeres gemeinsames Repository ist oft sinnvoll. Daher ist die bevorzugte Methode für die Zusammenarbeit, einen Zwischenspeicher einzurichten, auf den beide Seiten Zugriff haben, und von dem aus sie Push-to and Pull ausführen können.
Das Betreiben eines Git-Servers ist recht unkompliziert. Zuerst bestimmst du, welche Protokolle dein Server unterstützen soll. Der erste Abschnitt dieses Kapitels behandelt die verfügbaren Protokolle und deren Vor- und Nachteile. In den nächsten Abschnitten werden einige typische Setups mit diesen Protokollen erläutert und erklärt, wie du deinen Server mit diesen Protokollen zum Laufen bringst. Zuletzt werden wir ein paar gehostete Optionen durchgehen, falls du nicht den Aufwand der Einrichtung und Wartung deines eigenen Git-Servers auf dich nehmen willst.
Wenn du keinen eigenen Server betreiben möchtest, kannst du direkt zum letzten Abschnitt dieses Kapitels springen. Dort sind einige Optionen zum Einrichten eines gehosteten Kontos zu finden. Anschließend kannst du mit dem nächsten Kapitel fortfahren, in dem die verschiedenen Vor- und Nachteile der Arbeit in einer verteilten Versionskontrollumgebung erläutert werden.
Ein entferntes Repository ist in der Regel ein „nacktes Repository“ – ein Git-Repository, das kein Arbeitsverzeichnis hat.
Da das Repository nur als Kollaborationspunkt verwendet wird, gibt es erstmal keinen Grund, einen Snapshot auf die Festplatte speichern zu lassen; es enthält nur die Git-(Kontroll-)Daten.
Im einfachsten Fall besteht ein nacktes (eng. bare) Repository nur aus dem Inhalt des .git
Verzeichnisses deines Projekts.
Die Protokolle
Git kann vier verschiedene Protokolle für die Datenübertragung verwenden: Lokal, HTTP, Secure Shell (SSH) und Git. Hier werden wir klären, worum es sich handelt und unter welchen Rahmenbedingungen du sie verwenden oder nicht verwenden solltest.
Lokales Protokoll
Das einfachste ist das lokale Protokoll, bei dem sich das entfernte Repository in einem anderen Verzeichnis auf demselben Host befindet. Es wird häufig verwendet, wenn jeder in deinem Team Zugriff auf ein freigegebenes Dateisystem wie z.B. ein NFS-Mount hat, oder in dem selteneren Fall, dass sich jeder auf dem gleichen Computer anmeldet. Letzteres wäre nicht ideal, da sich alle deine Code-Repository-Instanzen auf demselben Computer befinden würden, was einen Totalverlust deiner Daten viel wahrscheinlicher macht.
Wenn Du ein geteiltes und gemountetes Dateisystem hast, kannst du von einem lokalel dateibasierten Repository klonen, etwas dort hin verschieben (engl. push to) und etwas daraus ziehen (engl. pull). Um solch ein repository zu klonen oder um es als remote zu einem existierenden Projekt hinzuzufügen, nutze einfach den Pfad zum Repository als URL. Um beispielsweise ein lokales Repository zu klonen, kannst du Folgendes ausführen:
$ git clone /srv/git/project.git
oder auch das:
$ git clone file:///srv/git/project.git
Git verhält sich ein wenig anders, wenn du file://
explizit am Anfang der URL angibst.
Wenn du nur den Pfad angibst, versucht Git, Hardlinks zu verwenden oder die benötigten Dateien direkt zu kopieren.
Wenn du file://
angibst, löst Git Prozesse aus, die normalerweise zum Übertragen von Daten über ein Netzwerk verwendet werden, was im Allgemeinen viel weniger effizient ist.
Der Hauptgrund für die Angabe des Präfix file://
ist, wenn du eine saubere Kopie des Repositorys mit irrelevanten Referenzen oder weggelassenen Objekten wünschst – in der Regel nach einem Import aus einem anderen VCS oder ähnlichem (siehe Git Interna für Wartungsaufgaben).
Wir werden hier den normalen Pfad verwenden, denn das ist fast immer schneller.
Um ein lokales Repository zu einem bestehenden Git-Projekt hinzuzufügen, kann folgendermaßen vorgegangen werden:
$ git remote add local_proj /srv/git/project.git
Dann kannst du über deinen neuen Remote-Namen local_proj
auf dieses Remote-Repository pushen und von dort abrufen, so wie du es auch über ein Netzwerk tun würdest.
Vorteile
Die Vorteile dateibasierter Repositorys liegen darin, dass sie simpel sind und vorhandene Datei- und Netzwerk-Berechtigungen verwenden. Wenn du bereits über ein freigegebenes Dateisystem verfügst, auf das dein gesamtes Team Zugriff hat, ist das Einrichten eines solchen Repositorys sehr einfach. Du speicherst die leere Repository-Kopie an einer Stelle, auf die jeder Zugriff hat und legst die Lese- und Schreibberechtigungen wie bei jedem anderen freigegebenen Verzeichnis fest. Informationen zum Exportieren einer Bare-Repository-Kopie für diesen Zweck findest du unter Git auf einem Server installieren.
Das ist auch eine elegante Möglichkeit, um schnell Arbeiten aus dem Arbeits-Repository eines anderen zu holen.
Wenn du und ein Mitstreiter am gleichen Projekt arbeiten und du etwas überprüfen möchtest, ist es oft einfacher, einen Befehl wie git pull /home/john/project
auszuführen, als auf einen Remote-Server zu pushen und anschließend von dort zu holen.
Nachteile
Der Nachteil dieser Methode ist, dass der gemeinsame Zugriff in der Regel schwieriger einzurichten ist damit man von mehreren Standorten aus erreichbar ist als der einfache Netzwerkzugriff. Wenn du von zu Hause mit deinem Laptop aus pushen möchtest, musst du das entfernte Verzeichnis einhängen (engl. mounten), was im Vergleich zum netzwerkbasierten Zugriff schwieriger und langsamer sein kann.
Es ist wichtig zu erwähnen, dass es nicht unbedingt die schnellste Option ist, wenn du einen gemeinsamen Mount verwendest. Ein lokales Repository ist nur dann schnell, wenn du schnellen Zugriff auf die Daten hast. Ein Repository auf NFS-Mounts ist oft langsamer als der Zugriff über SSH auf demselben Server, so kann Git Daten auf lokalen Festplatten auf jedem System speichern.
Schließlich schützt dieses Protokoll das Repository nicht vor unbeabsichtigten Schäden. Jeder Benutzer hat vollen Shell-Zugriff auf das „remote“ Verzeichnis, und nichts hindert ihn daran, interne Git-Dateien zu ändern oder zu entfernen und das Repository zu beschädigen.
HTTP Protokolle
Git kann über HTTP in zwei verschiedenen Modi kommunizieren. Vor Git 1.6.6 gab es nur einen einzigen Weg, der sehr einfach und im Allgemeinen „read-only“ war. Mit der Version 1.6.6 wurde ein neues, intelligenteres Protokoll eingeführt, bei dem Git in der Lage ist, den Datentransfer intelligent auszuhandeln, ähnlich wie bei SSH. In den letzten Jahren ist dieses neue HTTP-Protokoll sehr beliebt geworden, da es für den Benutzer einfacher und intelligenter in der Kommunikation ist. Die neuere Version wird oft als Smart HTTP Protokoll und die ältere als Dumb HTTP bezeichnet. Wir werden zuerst das neuere Smart HTTP-Protokoll besprechen.
Smart HTTP
Smart HTTP funktioniert sehr ähnlich wie die Protokolle SSH oder Git, läuft aber über Standard HTTPS-Ports und kann verschiedene HTTP-Authentifizierungsmechanismen verwenden. Das bedeutet, dass es für den Benutzer oft einfacher ist als so etwa SSH, da du Eingaben wie Benutzername/Passwort-Authentifizierung verwenden kannst, anstatt SSH-Schlüssel einrichten zu müssen.
Es ist wahrscheinlich der beliebteste Weg, heutzutage Git zu verwenden, da es so eingerichtet werden kann, dass es sowohl anonym wie das Protokoll git://
arbeitet, als auch mit Authentifizierung und Verschlüsselung wie das SSH-Protokoll betrieben werden kann.
Anstatt dafür verschiedene URLs einrichten zu müssen, kannst du nun eine einzige URL für beides verwenden.
Wenn du versuchst, einen Push durchzuführen und das Repository eine Authentifizierung erfordert (was normalerweise der Fall sein sollte), kann der Server nach einem Benutzernamen und einem Passwort fragen.
Gleiches gilt für den Lesezugriff.
Für Dienste, wie GitHub, ist die URL, die du verwendest, um das Repository online anzuzeigen (z.B. https://github.com/schacon/simplegit), die gleiche URL, mit der du klonen und, wenn du Zugriff hast, pushen kannst.
Dumb HTTP
Wenn der Server nicht mit einem Git HTTP Smart Service antwortet, versucht der Git Client, auf das einfachere Dumb HTTP Protokoll zurückzugreifen.
Das Dumb-Protokoll erwartet von dem Bare-Git-Repository, dass der Webserver seine Dateien ganz normal zur Verfügung stellt.
Das Schöne an Dumb HTTP ist die einfache Einrichtung.
Im Grunde genommen musst du nur ein leeres Git-Repository unter deinem HTTP-Dokument-Root legen und einen bestimmten post-update
Hook einrichten, und schon bist du fertig (siehe Git Hooks).
Ab diesem Zeitpunkt kann jeder, der auf den Webserver zugreifen kann, auf dem das Repository liegt, dein Repository klonen.
Um Lesezugriff auf dein Repository über HTTP zu ermöglichen, gehe wie folgt vor:
$ cd /var/www/htdocs/
$ git clone --bare /path/to/git_project gitproject.git
$ cd gitproject.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update
Das war’s.
Der post-update
Hook, der standardmäßig mit Git geliefert wird, führt den entsprechenden Befehl (git update-server-info
) aus, um den Abruf- und Klonvorgang über HTTP ordnungsgemäß zu ermöglichen.
Dieser Befehl wird ausgeführt, wenn du in dieses Repository pushst (z.B. über SSH); dann können andere folgendermaßen Klonen:
$ git clone https://example.com/gitproject.git
In diesem speziellen Fall verwenden wir den Pfad /var/www/htdocs
, der für Apache-Installationen üblich ist. Du kannst aber jeden statischen Webserver verwenden – lege einfach das leere Repository in seinen Pfad.
Die Git-Daten werden als einfache statische Dateien bereitgestellt (siehe Kapitel Git Interna für Bedienungsdetails).
Normalerweise würdest du entweder einen Smart HTTP-Server zum Lesen und Schreiben betreiben oder die Dateien einfach schreibgeschützt im Dumb-Modus zur Verfügung stellen. Ein Mix aus beiden Diensten wird selten angeboten.
Vorteile
Wir wollen uns auf die Vorteile der Smart Version des HTTP-Protokolls konzentrieren.
Die Tatsache, dass eine einzige URL für alle Zugriffsarten und der Server-Prompt nur dann gebraucht wird, wenn eine Authentifizierung erforderlich ist, macht die Sache für den Endbenutzer sehr einfach. Die Authentifizierung mit einem Benutzernamen und einem Passwort ist ebenfalls ein großer Vorteil gegenüber SSH, da Benutzer keine SSH-Schlüssel lokal generieren und ihren öffentlichen Schlüssel auf den Server hochladen müssen, bevor sie mit ihm interagieren können. Für weniger anspruchsvolle Benutzer oder Benutzer auf Systemen, auf denen SSH weniger verbreitet ist, ist dies ein großer Vorteil in der Benutzerfreundlichkeit. Es ist auch ein sehr schnelles und effizientes Protokoll, ähnlich dem SSH-Protokoll.
Du kannst dein Repositorys auch schreibgeschützt über HTTPS bereitstellen, d.h. du kannst die Inhaltsübertragung verschlüsseln oder sogar so weit gehen, dass Clients bestimmte signierte SSL-Zertifikate verwenden müssen.
Eine weitere schöne Sache ist, dass HTTP und HTTPS ein so häufig verwendetes Protokoll ist. Unternehmens-Firewalls sind oft so eingerichtet, dass sie den Datenverkehr über deren Ports erlauben.
Nachteile
Git über HTTPS kann im Vergleich zu SSH auf einigen Servern etwas komplizierter einzurichten sein. Abgesehen davon gibt es sehr wenig Vorteile, die andere Protokolle gegenüber Smart HTTP für die Bereitstellung von Git-Inhalten haben.
Wenn du HTTP für authentifiziertes Pushen verwendest, ist die Bereitstellung deiner Anmeldeinformationen manchmal komplizierter als die Verwendung von Schlüsseln über SSH. Es gibt jedoch mehrere Tools zum Zwischenspeichern von Berechtigungen, die du verwenden kannst, darunter Keychain-Zugriff auf macOS und Credential Manager unter Windows, um das zu Vereinfachen. Lese den Abschnitt Credential Storage, um zu erfahren, wie du ein sicheres HTTP-Passwort-Caching auf deinem System einrichten kannst.
SSH Protocol
Ein gängiges Git-Transportprotokoll für Self-Hosting ist SSH. Der SSH-Zugriff auf den Server ist in den meisten Fällen bereits eingerichtet – und wenn nicht, ist es einfach zu bewerkstelligen. SSH ist auch ein authentifiziertes Netzwerkprotokoll, und da es allgegenwärtig ist, ist es im Allgemeinen einfach einzurichten und zu verwenden.
Um ein Git-Repository über SSH zu klonen, kannst du eine entsprechende ssh://
URL angeben:
$ git clone ssh://[user@]server/project.git
Oder kannst die kürzere scp-ähnliche Syntax für das SSH-Protokoll verwenden:
$ git clone [user@]server:project.git
Wenn du in beiden Fällen oben keinen optionalen Benutzernamen angibst, benutzt Git den User, mit dem du aktuell angemeldet bist.
Vorteile
Die Vorteile bei der Verwendung von SSH sind vielfältig. Erstens ist SSH relativ einfach einzurichten – SSH-Daemons sind weit verbreitet, viele Netzwerkadministratoren haben Erfahrung mit ihnen und viele Betriebssystem-Distributionen werden mit ihnen eingerichtet oder haben Werkzeuge, um sie zu verwalten. Als nächstes ist der Zugriff über SSH sicher – der gesamte Datentransfer wird verschlüsselt und authentifiziert. Schließlich ist SSH, wie die Protokolle HTTPS, Git und Local effizient und komprimiert die Daten vor der Übertragung so stark wie möglich.
Nachteile
Die negative Seite von SSH ist, dass es keinen anonymen Zugriff auf dein Git-Repository unterstützt. Wenn du SSH verwendest, müssen Benutzer über einen SSH-Zugriff auf deinen Computer verfügen, auch wenn sie nur über Lesezugriff verfügen. Das macht SSH in Open Source-Projekten ungeeignet. Bspw. wenn die Benutzer dein Repository einfach nur klonen möchten, um es zu überprüfen. Wenn du es nur in deinem Unternehmensnetzwerk verwendest, ist SSH möglicherweise das einzige Protokoll, mit dem du dich befassen musst. Wenn du anonymen schreibgeschützten Zugriff auf deine Projekte und auch SSH zulassen möchtest, musst du SSH einrichten, damit du Push-Vorgänge ausführen kannst. Zusätzlich musst du jedoch noch etwas anderes konfigurieren damit Benutzer auch anonym abrufen können.
Git Protokoll
Zuletzt haben wir noch das Git-Protokoll.
Es ist ein spezieller Daemon, der mit Git ausgeliefert wird. Er lauscht auf einem dedizierten Port (9418) und stellt einen Dienst bereit, ähnlich dem des SSH-Protokolls, jedoch ohne jegliche Authentifizierung oder Verschlüsselung.
Damit ein Repository über das Git-Protokoll bedient werden kann, musst du eine git-daemon-export-ok
Datei erstellen – der Daemon wird ohne diese Datei kein Repository bedienen, da es ansonsten keine Sicherheit gibt.
Entweder ist das Git-Repository für jeden oder für niemanden zum klonen zugänglich.
Das bedeutet, dass es in der Regel keinen Push über dieses Protokoll gibt.
Du kannst den Push-Zugriff aktivieren, aber angesichts der fehlenden Authentifizierung kann jeder im Internet, der die URL deines Projekts findet, in dieses Projekt pushen.
Somit sollte klar sein, dass es sehr selten vorkommt.
Vorteile
Das Git-Protokoll ist oft als erstes Netzwerkübertragungsprotokoll verfügbar. Wenn du viele Daten für ein öffentliches Projekt bereitstellst oder du ein ein sehr großes Projekt bedienst, das keine Benutzerauthentifizierung für den Lesezugriff benötigt, dann könntest du den Git-Daemon einrichten, um das Projekt zu unterstützen. Er verwendet den gleichen Datenübertragungsmechanismus wie das SSH-Protokoll, jedoch ohne den Aufwand der Verschlüsselung und Authentifizierung.
Nachteile
Aufgrund des Fehlens von TLS oder einer anderer Verschlüsselung kann das Klonen über „git://“ zu der Schwachstelle der Ausführung willkürlichen Codes führen und sollte daher vermieden werden, es sei denn, du weißt genau, was du tust.
-
Wenn du
git clone git://example.com/project.git
ausführst, kann ein Angreifer, der z. B. deinen Router kontrolliert, das gerade geklonte Repo modifizieren und bösartigen Code injizieren. Wenn du dann den gerade geklonten Code kompilieren/ausführen möchtest, führst du stattdessen diesen bösartigen Code aus. Das Ausführen vongit clone http://example.com/project.git
sollte aus demselben Grund vermieden werden. -
Das Ausführen von
git clone https://example.com/project.git
hat dieses Problem nicht (es sei denn, der Angreifer kann ein TLS-Zertifikat für example.com bereitstellen). Das Ausführen vongit clone git@example.com:project.git
hat nur dann dieses Problem, wenn du einen falschen ssh-key fingerprint akzeptierst.
Es hat auch keine Authentifizierung, d.h. jeder kann das Repo klonen (obwohl dies oft genau das ist, was du willst).
Es ist wahrscheinlich auch das am schwierigsten einzurichtende Protokoll.
Ein proprietärer Daemon muss laufen, der eine xinetd
oder systemd
Konfiguration oder dergleichen erfordert, was nicht immer einfach ist.
Es erfordert auch einen Firewall-Zugang auf Port 9418, der kein Standardport ist, den Unternehmens-Firewalls zulassen.
Hinter großen Firmen-Firewalls wird dieser „obskure“ Port häufig blockiert.