Git 🌙
Chapters ▾ 2nd Edition

10.5 Git Interna - Die Referenzspezifikation (engl. Refspec)

Die Referenzspezifikation (engl. Refspec)

In diesem Buch haben wir simple Zuordnungen von remote Branches zu lokalen Referenzen verwendet, diese können jedoch komplexer sein. Angenommen, du hast die letzten Abschnitte mitverfolgt und ein kleines lokales Git-Repository erstellt, und möchtest nun einen remote hinzufügen:

$ git remote add origin https://github.com/schacon/simplegit-progit

Durch Ausführen des obigen Befehls wird ein Abschnitt zur .git/config Datei deines Repositorys hinzugefügt. Es wird der Name des Remote-Repositorys (origin), die URL des Remote-Repositorys und die refspec angegeben sind, die zum Abrufen verwendet werden soll:

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*

Das Format der Refspec ist zunächst ein optionales +, gefolgt von <src>:<dst>, wobei <src> das Muster für Referenzen auf der Remote-Seite ist. <dst> gibt an wo diese Referenzen lokal nachverfolgt werden. Das + weist Git an, die Referenz zu aktualisieren, auch wenn es sich nicht um einen fast-forward handelt.

In der Standardeinstellung, die automatisch von einem Befehl git remote add origin geschrieben wird, ruft Git alle Referenzen unter refs/heads/ auf dem Server ab und schreibt sie lokal in refs/remotes/origin/. Wenn sich auf dem Server also ein master Branch befindet, kannst du auf das Log dieses Branches lokal zugreifen, indem du eine der folgenden Aktionen ausführst:

$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master

Sie sind alle gleichwertig, da Git sie zu refs/remotes/origin/master erweitert.

Wenn Git stattdessen jedes Mal nur den master Branch und nicht jeden anderen Branch auf dem Remote-Server pullen soll, kannst du die Abrufzeile so ändern, dass sie nur auf diesen Branch verweist:

fetch = +refs/heads/master:refs/remotes/origin/master

Dies ist nur die Standard Refspec für git fetch für diesen Remote. Wenn du einen einmaligen Abruf durchführen möchtest, kannst du die spezifische Refspec auch in der Befehlszeile angeben. Um den master Branch auf dem Remote lokal nach origin/mymaster zu pullen, kannst du Folgendes ausführen:

$ git fetch origin master:refs/remotes/origin/mymaster

Du kannst auch mehrere Refspecs angeben. In der Befehlszeile kannst du mehrere Branches wie folgt pullen:

$ git fetch origin master:refs/remotes/origin/mymaster \
	 topic:refs/remotes/origin/topic
From git@github.com:schacon/simplegit
 ! [rejected]        master     -> origin/mymaster  (non fast forward)
 * [new branch]      topic      -> origin/topic

In diesem Fall wurde der master Branch pull abgelehnt, da er nicht als Fast-Forward aufgeführt war. Du kannst dies überschreiben, indem du das + vor der Refspec angibst.

Du kannst auch mehrere Refspecs zum Abrufen in deiner Konfigurationsdatei angeben. Wenn du immer die Branches master und experiment vom origin Remote abrufen möchtest, füge zwei Zeilen hinzu:

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/master:refs/remotes/origin/master
	fetch = +refs/heads/experiment:refs/remotes/origin/experiment

Seit Git 2.6.0 kannst du partielle Globs in Pattern verwenden, um mehrere Branches anzupassen, dann funktioniert das hier:

fetch = +refs/heads/qa*:refs/remotes/origin/qa*

Noch besser, du kannst Namespaces (oder Verzeichnisse) verwenden, um dasselbe mit mehr Struktur zu erreichen. Wenn du ein QS-Team hast, das eine Reihe von Branches pusht, und du möchtest nur den master Branch und einen der Branches des QS-Teams erhalten, dann kannst du einen Konfigurationsabschnitt wie diesen verwenden:

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/master:refs/remotes/origin/master
	fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*

Wenn du über einen komplexen Workflow-Prozess verfügst, bei dem QS-Team und Entwickler Branches pushen und Integrationsteams auf Remotebranches pushen bzw. daran zusammenarbeiten, kannst du sie auf diese Weise problemlos mit Namespaces versehen.

Pushende Refspecs

Es ist schön, dass du auf diese Weise Referenzen mit Namespaces abrufen kannst, aber wie bringt das QS-Team seine Branches überhaupt an die erste Stelle eines Namespace qa/? Du erreichst dies, indem du Refspecs zum Pushen verwendest.

Wenn das QS-Team seinen master Branch auf qa/master auf dem Remote-Server verschieben möchte, kann folgendes ausgeführt werden:

$ git push origin master:refs/heads/qa/master

Wenn Git dies bei jedem Start von git push origin automatisch ausführen soll, können sie ihrer Konfigurationsdatei einen push Wert hinzufügen:

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*
	push = refs/heads/master:refs/heads/qa/master

Dies wird wiederum dazu führen, dass ein git push origin den lokalen master Branch standardmäßig zum remote qa/master Branch pusht.

Anmerkung

Du kannst die Refspec nicht zum Abrufen von einem Repository und zum Verschieben auf ein anderes Repository verwenden. Ein Beispiel wie das geht findest du unter Dein öffentliches GitHub-Repository aktuell halten.

Löschende Referenzen

Du kannst mit Refspec auch Verweise vom Remote-Server löschen, indem du Folgendes ausführst:

$ git push origin :topic

Die Syntax der Refspezifikation lautet <src>:<dst>. Das Weglassen des <src> Teils bedeutet im Grunde genommen, dass der topic Branch auf dem Remote leer bleibt, wodurch er gelöscht wird.

Oder du kannst die neuere Syntax verwenden (verfügbar seit Git v1.7.0):

$ git push origin --delete topic
scroll-to-top