Die Refspec
In diesem Buch haben wir bisher einfache Zuweisungen von externen Branches auf lokale Referenzen verwendet. Sie können aber auch durchaus komplex sein. Nehmen wir an, Du hast ein Remote-Repository wie folgt definiert:
$ git remote add origin [email protected]:schacon/simplegit-progit.git
Das fügt eine Sektion in Deine .git/config
-Datei hinzu, die Deinen lokalen Namen des externen Repositorys (origin
), dessen URL und die Refspec spezifiziert, mit der neue Daten heruntergeladen werden.
[remote "origin"]
url = [email protected]:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
Das Format der Refspec besteht aus einem optionalen +
gefolgt von <Quelle>:<Ziel>
, wobei <Quelle>
ein Muster für Referenzen auf der Remote-Seite ist, und <Ziel>
angibt, wohin diese Referenzen lokal geschrieben werden. Das +
weist Git an, die Referenz zu mergen, wenn sie nicht mit einem Fast-forward aktualisiert werden kann.
Der Standard, der von git remote add
automatisch eingerichtet wird, besteht darin, dass Git automatisch alle Referenzen unter refs/heads/
vom Server holt und sie lokal nach refs/remotes/origin
speichert. D.h., wenn es auf dem Server einen Branch master
gibt, kannst Du auf das Log dieses Branches wie folgt zugreifen:
$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master
Diese Varianten sind allesamt äquivalent, weil Git sie jeweils zu refs/remotes/origin/master
vervollständigt.
Wenn Du stattdessen willst, dass Git jeweils nur den Branch master
herunterlädt und andere Branches auf dem Server ignoriert, kannst Du die fetch
-Zeile wie folgt ändern:
fetch = +refs/heads/master:refs/remotes/origin/master
Dies ist allerdings lediglich der Standardwert der Refspec und Du kannst ihn auf der Kommandozeile jederzeit überschreiben. Um zum Beispiel nur den Branch master
vom Server lokal als origin/mymaster
zu speichern, kannst Du Folgendes ausführen:
$ git fetch origin master:refs/remotes/origin/mymaster
Du kannst auch mehrere Refspecs gleichzeitig spezifizieren. Um mehrere Branches zu holen kannst du folgenden Befehl in die Kommandozeile eingeben:
$ git fetch origin master:refs/remotes/origin/mymaster \
topic:refs/remotes/origin/topic
From [email protected]:schacon/simplegit
! [rejected] master -> origin/mymaster (non fast forward)
* [new branch] topic -> origin/topic
In diesem Fall wurde ein Pull zurückgewiesen, weil der Branch nicht mit einem simplen Fast-forward aktualisiert werden konnte. Du kannst einen Merge erzwingen, indem Du der Refspec ein +
voranstellst.
Du kannst außerdem natürlich auch mehrere Refspecs in Deiner Konfiguration spezifizieren. Wenn Du z.B. immer die Branches master
und experiment
holen willst, fügst Du die folgenden Zeilen hinzu:
[remote "origin"]
url = [email protected]:schacon/simplegit-progit.git
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/experiment:refs/remotes/origin/experiment
Du kannst keine partiellen Glob-Muster verwenden, d.h. Folgendes wäre ungültig:
fetch = +refs/heads/qa*:refs/remotes/origin/qa*
Allerdings kannst Du Namensräume verwenden, um etwas Ähnliches zu erreichen. Nehmen wir an, Du hast ein QA-Team, das regelmäßig verschiedene Branches pusht, und Du willst nun den Branch master und sämtliche Branches des QA-Teams, aber keine anderen Branches haben. Dann kannst Du eine Config-Sektion wie die folgende verwenden:
[remote "origin"]
url = [email protected]:schacon/simplegit-progit.git
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
In einem großen Team mit einem komplexen Workflow, in dem ein QA-Team, Entwickler und ein Integrations-Team jeweils eigene Branches pushen, kann man auf diese Weise Branches einfach in Namensräume einteilen.
Refspecs pushen
Wie aber legt das QA-Team die Branches im qa/
Namensraum ab? Das geht, indem man mit einer Refspec pusht.
Wenn das QA-Team seinen Branch master
in einem externen Repository als qa/master
speichern will, kann es das wie folgt tun:
$ git push origin master:refs/heads/qa/master
Um Git so zu konfigurieren, dass diese Refspec jedes Mal automatisch für git push origin
verwendet wird, kann man den push
Wert in der Config-Datei setzen:
[remote "origin"]
url = [email protected]:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/qa/master
Auf diese Weise wird git push origin
den lokalen Branch master
als qa/master
auf dem Server origin
speichern.
Referenzen löschen
Man kann Refspecs außerdem verwenden, um Referenzen aus einem externen Repository zu löschen:
$ git push origin :topic
Das Refspec Format ist <Quelle>:<Ziel>
. Wenn man den Teil <Quelle>
weglässt, dann heißt das im obigen Beispiel, dass man den Branch topic
auf dem Server origin
auf „nichts“ setzt, d.h. also löscht.