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 git@github.com: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 = git@github.com: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 git@github.com: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 = git@github.com: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 = git@github.com: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.
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 = git@github.com: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.
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.