
Im Grunde funktioniert git
dezentral, das heißt, dass prinzipell jeder Client gleichberechtigt ist, und keine:r der Teilnehmer:innen eines Projekts Autorität über den gerade gültigen Stand eines Repositories besitzt. In der Praxis wird jedoch immer ein zentrales Repository als Referenz genutzt. Ein Server hostet den de facto gültigen Status eines Projekts, der zwar gewaltsam überschrieben werden kann, aber nie sollte (mehr dazu unten).
Weil Server, im Gegensatz zu einzelnen Rechnern, immer eingeschaltet sind und im offenen Netz stehen, benutzt man in der Regel einen Anbieter, der das autoritative Repository hostet. Die bekanntesten Anbieter sind GitHub, GitLab und Bitbucket. Software wie Gitea oder Gogs ermöglichen es auch, eigene Git-Server zu betreiben, was aber wegen des hohen Aufwands und der geringen Vorteile nur von sehr großen oder firmeninternen Projekten gemacht wird.
Begriffe #
remote/origin #
Remote ist ein Verweis auf ein entferntes Repository, das auf einem Server liegt. Der Standardname für das entfernte Repository ist origin
. Mit git remote
können alle entfernten Repositories angezeigt werden, mit git remote -v
werden auch die URLs angezeigt. Mit git remote add <name> <url>
kann ein neues entferntes Repository hinzugefügt werden, mit dem synchronisiert werden kann.
history #
Die history ist essentiell eine commit-Kette, angefangen vom letzten – neuesten – commit bis zum ersten, der keine Eltern hat. Die history, einmal geschrieben, ist zwar nicht unveränderbar, aber eine Veränderung der history ist mit hohem Aufwand und einem Bruch der Zusammenarbeit verbunden. Commits selbst können nicht geändert, nur neu geschrieben werden; wird also ein commit in der Kette geändert, so müssen alle folgenden commits ebenfalls neu geschrieben werden.
Es gibt geeignetere Methoden, zu einem früheren Stand zurückzukehren.
merge #
Falls mehere Teilnehmer:innen gleichzeitig an einem Projekt arbeiten, kann es passieren, dass upstream commits bereitstellt, die lokal nicht vorhanden sind.
In diesem Fall muss ein merge durchgeführt werden, um die Änderungen zusammenzuführen.
git
versucht, den merge automatisch durchzuführen, und erstellt einen neuen commit, der die Änderungen vereint.
In der Regel ist das kein Problem, da die meisten Teilnehmer:innen an verschiedenen Teilen des Projekts (beispielsweise unterschiedliche Dateien, oder ganz andere Zeilen innerhalb einer Datei) arbeiten.
Manchmal kann es aber bei widersprüchlichen Änderungen zu Konflikten kommen, die manuell gelöst werden müssen (s.u. Merge-Workflow).
Befehle #
git clone #
git clone <url>
git clone
erstellt initial eine Kopie eines entfernten Repositories auf dem lokalen Rechner. Der Standardname für das entfernte Repository ist origin
. Der erstellte Ordner trägt den Namen des Repositories. Jede:r Teilnehmer:in erhält eine eigene Kopie des Repositories, mit allen jemals daran getätigten Änderungen. Die lokale Version funktioniert unabhängig und offline von der öffentlichen.
git pull #
git pull <pfad>
git pull
lädt alle Änderungen aus dem entfernten Repository herunter und führt die Änderungen, falls nötig, zusammen.
Bei einem
pull
kann es zu einem Merge-Konflikt kommen.Es ist sinnvoll, vor jeder Arbeit einen pull durchzuführen, um unnötige Konflikte zu vermeiden.
git push #
git push
git push
lädt alle lokalen commits in das entfernte Repository hoch und veröffentlicht sie. Der Befehl git push
wird manchmal mit dem Namen des entfernten Repositories und des Branches kombiniert, z.B. git push origin master
.
git push
kann auch mit --tags
kombiniert werden, um Tags zu veröffentlichen.
Der Server lehnt einen
push
ab, wenn remote neue commits vorliegen. In einem solchen Fall sollte eingit pull
durchgeführt werden, um die Änderungen zu integrieren.
Manchmal wird in Foren ein
git push --force
zur Lösung eines Problems angeraten. Der Server wird damit angewiesen, seine history mit der lokalen zu überschreiben.Normalerweise hat es aber einen einfachen Grund, dass der Server einen push ablehnt: jemand hat in der Zwischenzeit ebenfalls commits gepusht. Ein einfacher
git pull
und ein merge commit beheben in 99.9% aller Fälle das Problem.Manchmal muss ein Administrator einen solchen force-push durchführen, um beispielsweise unabsichtlich eingecheckte Zugangsdaten aus der history zu tilgen. Ein
git push --force
sollte nur in Ausnahmefällen und nach Absprache mit allen Beteiligten durchgeführt werden.
Hinweise #
Wie können Änderungen rückgängig gemacht machen? #
git restore [--source <tree-like>] <pfad>
restore
ist ein neuerer, ungefährlicher Befehl, der dazu dient, Änderungen in Dateien zurückzusetzen. Meistens, wenn man einen früheren Dateistand wiederherstellen möchte, istrestore
der gesuchte Command.
restore
wird primär dazu genutzt, Änderungen von einzelnen Dateien aus dem Stageing-Bereich zu entfernen und wird vongit status
dazu empfohlen. Mithilfe vonrestore
können auch commits rückgängig gemacht werden, aber so, dass die history nicht neu geschrieben wird. Dabei wird ein commit erstellt, der Änderungen rückgängig macht.
git revert <commit>
Auch mit
revert
kann man relativ ungefährdet einen früheren Dateizustand wiederherstellen. Wie mitrestore
oben kann mitrevert
ein neuer commit erstellt, der die Änderungen eines früheren commits im Ganzen rückgängig macht.revert
ist ein sicherer Weg, um Änderungen rückgängig zu machen, ohne die history zu verändern.
restore
undrevert
unterscheiden sich darin, dassrestore
Änderungen in Dateien zurücksetzt und sich ohne Angabe von--source
auf den Stageing-Bereich bezieht, währendrevert
ganze commits rückgängig macht.
git checkout <pfad | tree-like>
Wenn Änderungen in den Dateien zurückgesetzt werden sollen, die noch nicht in einem commit sind, kann
git checkout
benutzt werden. So werden alle Dateien eines Verzeichnisses beispielsweise mitgit checkout .
in den Zustand des letzten commits zurückgesetzt. Dieser Befehl wird oft benutzt, wenn man kurzfristig etwas kaputt gemacht hat, aber jetzt nicht das Repo neu clonen möchte.Achtung! Dabei gehen Änderungen an Dateien verloren, die nicht committed wurden.
git reset [--soft | --hard] <commit-like>
reset
kann die History neu schreiben. Früher wurdereset
u.a. dazu benutzt, Änderungen aus dem Index zu entfernen und vongit status
dazu empfohlen. Heute wirdgit restore
empfohlen, um Änderungen aus dem Stageing-Bereich zu nehmen.reset
sollte nur in Ausnahmefällen und nach Absprache mit allen Beteiligten durchgeführt werden.
Git Rebase #
git rebase <branch>
rebase
ist ein mächtiges Werkzeug, um die history zu bereinigen und zu vereinfachen. So kann eine vielverzweigte hisory damit “gestrafft” werden.rebase
sollte aber nur in den eigenen branches und niemals in branches, die mit anderen geteilt werden, durchgeführt werden. Einrebase
impliziert fast immer einenforce-push
und sollte nur nach Absprache mit allen Beteiligten durchgeführt werden.