Logo von Developer

Suche
preisvergleich_weiss

Recherche in 2.273.563 Produkten

Andreas Krüger 117

Repo mit einem Commit

Im normalen Entwickleralltag nutzt man die Standardmöglichkeiten von Git. Aber gelegentlich können selten genutzte Fähigkeiten das Leben angenehmer machen – wenn man sie denn kennt.

Die bisher vorgeschlagene Methode der Zusammenarbeit von A und B basiert auf vollwertigen Repositorys, die jeweils die gesamte Vergangenheit des Projekts mit an Bord haben. Die historische Vollständigkeit ist manchmal nützlich, aber gelegentlich auch überflüssiger Ballast. Das Hauptthema der Artikelserie, "Vielzahl statt Einzahl", wird deshalb hier kurzfristig umgekehrt: Es soll im Folgenden von Repositorys die Rede sein, die statt der sonst üblichen Gesamthistorie nur einen Commit enthalten.

Eine (teilweise) Kopie eines Repositorys mit unvollständiger Historie nennt die Git-Dokumentation "shallow". Man erzeugt sie mit einer entsprechenden --depth-Option von git clone.

Shallow Clone (Abb. 6)
Shallow Clone (Abb. 5)

Als Beispiel soll eine Zusammenarbeit zwischen A und B auf dem Feature-Branch f_branch erfolgen. Den hat A bereits angelegt. Dann kann A ein Repository nur mit dem letzten Commit von f_branch erzeugen und an B weitergeben. Das geht notfalls sogar ohne eigenen Git-Server.

Angenommen, das lokale Repo von A liegt in $HOME/lokal-repo. Dann erzeugt A die unvollständige Kopie (in einem Verzeichnis, das vorzugsweise gerade nicht in einem Git-Worktree liegt) mit:

git clone --bare --single-branch -b f_branch --depth 1 file://$HOME/lokal-repo

Die erzeugte teilweise Repository-Kopie enthält zunächst noch einen Verweis auf das eigene lokale $HOME/lokal-repo. Den entfernt A:

git remote remove origin

Das präparierte Repository kann A nun in ein ZIP-Archiv oder Ähnliches einpacken und auf passendem Weg B zur Verfügung stellen. Das empfiehlt sich vor allem, wenn ein SSH-Server noch nicht gefunden ist, die Netzwerkverbindung zwischen A und B lahmt und B möglichst schnell loslegen soll.

B packt das Archiv wieder aus und nutzt das entstehende Repository als Basis für eine git clone-Operation. Mit dem daraus entstehenden Arbeits-Repository arbeitet B lokal wie gewohnt weiter.

Später soll B Ergebnisse zur Verfügung stellen. Man kann dann problemlos nachträglich auf einen gemeinsam erreichbaren Klon aufrüsten, auf den B Schreibzugriff hat, zum Beispiel ssh-basiert wie oben.

Haben sich nur Textdateien geändert, kann B eine Patch-Datei an A schicken, also den Output von git diff. Das geht bequem via E-Mail. Mit git apply und anschließendem git commit --author ... kann A die Ergebnisse von B lokal integrieren.

Teilweise Kopieren: Auch sonst nützlich!

Die Idee, sich beim Kopieren eines Repositorys auf den letzten Commit zu beschränken, ist auch sonst gelegentlich nützlich. Viele Builds, CI-Pipelines und ähnliche automatisierte Prozesse können auf einfache Weise erheblich beschleunigt werden, wenn einem ohnehin vorhandenen git clone die Option --depth 1 mitgegeben wird.

Derselbe Trick kann ebenfalls hilfreich sein, wenn man auf den Inhalt eines Open-Source-Repositorys neugierig ist. Man will gerne so schnell wie möglich einen Worktree auf der eigenen Festplatte begutachten können. Die Historie des Repositorys interessiert erst später, in zweiter Linie.

In diesem Fall besorgt man sich das Repository zunächst mit git clone --depth 1. Das geht schnell, entsprechend bald kann man anfangen, sich im Worktree umzusehen. Währenddessen lässt man im Hintergrund den langen Download der Gesamthistorie laufen:

git fetch --unshallow

Wenn man das auf einem Repository mit vollständiger Historie aufruft, erscheint natürlich eine Fehlermeldung. Bei einigen Git-Versionen ist die Fehlermeldung verwirrend falsch ins Deutsche übersetzt:

Die Option --unshallow kann nicht in einem Repository mit unvollständiger Historie verwendet werden.

Das sollte eigentlich "... mit vollständiger Historie ..." heißen.

Wenn man von einem Repository beim initialen Klonen nur den letzten Commit haben wollte, holt Git auch bei späteren git fetch-Operationen zunächst nur den betreffenden Branch. Bei von Anfang an komplett geklonten Repositorys holt git fetch dagegen normalerweise alle vorhandenen Branches. Man kann nachträglich mit folgender Zeile konfigurieren, dass alle Branches geholt werden sollen:

git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'

117 Kommentare

Themen: