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, Sie haben die letzten Abschnitte mitverfolgt und ein kleines lokales Git-Repository erstellt, und möchten nun eine 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 Ihres 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 git remote add origin-Befehl 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, können Sie auf das Log dieses Branches lokal zugreifen, indem Sie eine der folgenden Aktionen ausführen:

$ 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, können Sie 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 Sie einen einmaligen Abruf durchführen möchten, können Sie die spezifische Refspec auch in der Befehlszeile angeben. Um den master-Branch auf dem Remote lokal nach origin/mymaster zu pullen, können Sie Folgendes ausführen:

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

Sie können auch mehrere Refspecs angeben. In der Befehlszeile können Sie 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. Sie können dies überschreiben, indem Sie das + vor der Refspec angeben.

Sie können auch mehrere Refspecs zum Abrufen in Ihrer Konfigurationsdatei angeben. Wenn Sie immer die Branches master und experiment vom origin-Remote abrufen möchten, fügen Sie 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

Sie können keine partiellen Globs im Pattern verwenden, folgendes wäre also ungültig:

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

Sie können jedoch Namespaces (oder Verzeichnisse) verwenden, um dies zu erreichen. Wenn Sie ein QS-Team haben, das eine Reihe von Branches pusht, und Sie möchten nur den master-Branch und einen der Branches des QS-Teams erhalten, dann können Sie 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 Sie über einen komplexen Workflow-Prozess verfügen, bei dem QS-Team und Entwickler Branches pushen und Integrationsteams auf Remotebranches pushen bzw. daran zusammenarbeiten, können Sie sie auf diese Weise problemlos mit Namespaces versehen.

Pushende Refspecs

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

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.

Note

Sie können die Refspec nicht zum Abrufen von einem Repository und zum Verschieben auf ein anderes Repository verwenden. Ein Beispiel wie das geht finden Sie unter Ihr öffentliches GitHub-Repository aktuell halten.

Löschende Referenzen

Sie können mit Refspec auch Verweise vom Remote-Server löschen, indem Sie Folgendes ausführen:

$ 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 Sie können die neuere Syntax verwenden (verfügbar seit Git v1.7.0):

$ git push origin --delete topic