Kapitel ▾ 2. Auflage

10.5 Git Internals - Die Refspec

Die Refspec

In diesem Buch haben wir einfache Zuordnungen von Remote-Zweigen zu lokalen Referenzen verwendet, aber sie können komplexer sein. Angenommen, Sie sind den letzten Abschnitten gefolgt und haben ein kleines lokales Git-Repository erstellt und möchten nun ein Remote hinzufügen

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

Die Ausführung des obigen Befehls fügt Ihrem Repository eine Sektion in der Datei .git/config hinzu, die den Namen des Remotes (origin), die URL des Remote-Repositories und die zu verwendende Refspec für das Abrufen angibt.

[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 und <dst> dort ist, wo diese Referenzen lokal verfolgt werden. Das + weist Git an, die Referenz zu aktualisieren, auch wenn es keine Fast-Forward-Aktualisierung ist.

Im Standardfall, der 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 unter refs/remotes/origin/. Wenn es also einen master-Zweig auf dem Server gibt, können Sie den Log dieses Zweigs lokal über einen der folgenden Wege aufrufen:

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

Sie sind alle gleichwertig, da Git jeden von ihnen zu refs/remotes/origin/master erweitert.

Wenn Sie stattdessen möchten, dass Git jedes Mal nur den master-Zweig herunterlädt und nicht jeden anderen Zweig auf dem Remote-Server, können Sie die Fetch-Zeile ändern, um nur auf diesen Zweig zu verweisen.

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

Dies ist nur die Standard-Refspec für git fetch für dieses Remote. Wenn Sie einen einmaligen Fetch durchführen möchten, können Sie die spezifische Refspec auch auf der Befehlszeile angeben. Um den master-Zweig vom Remote lokal nach origin/mymaster zu ziehen, können Sie Folgendes ausführen:

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

Sie können auch mehrere Refspecs angeben. Auf der Befehlszeile können Sie mehrere Zweige wie folgt herunterladen:

$ 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 Abruf des master-Zweigs abgelehnt, da er nicht als Fast-Forward-Referenz aufgeführt war. Sie können dies überschreiben, indem Sie das + vor der Refspec angeben.

Sie können auch mehrere Refspecs für das Abrufen in Ihrer Konfigurationsdatei angeben. Wenn Sie immer die master- und experiment-Zweige 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

Seit Git 2.6.0 können Sie partielle Globs im Muster verwenden, um mehrere Zweige abzugleichen. Daher funktioniert dies:

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

Noch besser ist es, Namespaces (oder Verzeichnisse) zu verwenden, um dasselbe mit mehr Struktur zu erreichen. Wenn Sie ein QA-Team haben, das eine Reihe von Zweigen pusht, und Sie den master-Zweig und alle Zweige des QA-Teams erhalten möchten, aber nichts anderes, 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 einen komplexen Workflow-Prozess haben, bei dem ein QA-Team Zweige pusht, Entwickler Zweige pushen und Integrationsteams an Remote-Zweigen pushen und zusammenarbeiten, können Sie diese auf diese Weise einfach in Namespaces aufteilen.

Pushing Refspecs

Es ist schön, dass Sie auf diese Weise Namespaced-Referenzen abrufen können, aber wie gelangen die Zweige des QA-Teams überhaupt in einen qa/-Namespace? Dies erreichen Sie durch die Verwendung von Refspecs zum Pushen.

Wenn das QA-Team seinen master-Zweig nach qa/master auf dem Remote-Server pushen möchte, kann es Folgendes ausführen:

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

Wenn es möchte, dass Git dies jedes Mal automatisch ausführt, wenn es git push origin ausführt, kann es der 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

Auch dies führt dazu, dass ein git push origin den lokalen master-Zweig standardmäßig zum Remote qa/master pusht.

Hinweis

Sie können die Refspec nicht verwenden, um aus einem Repository abzurufen und in ein anderes zu pushen. Ein Beispiel dafür finden Sie unter Halten Sie Ihr öffentliches GitHub-Repository auf dem neuesten Stand.

Referenzen löschen

Sie können die Refspec auch verwenden, um Referenzen vom Remote-Server zu löschen, indem Sie etwas wie das Folgende ausführen:

$ git push origin :topic

Da die Refspec <src>:<dst> ist, wird durch Weglassen des <src>-Teils im Wesentlichen gesagt, dass der topic-Zweig auf dem Remote leer sein soll, was ihn löscht.

Oder Sie können die neuere Syntax verwenden (verfügbar seit Git v1.7.0)

$ git push origin --delete topic