Die Refspec
Throughout this book, you’ve used simple mappings from remote branches to local references; but they can be more complex. Suppose you add a remote like this:
In diesem Buch haben wir bisher einfache Mappings von externen Branches auf lokale Referenzen verwendet. Sie können aber auch durchaus komplex sein. Nehmen wir an, du hast ein externes Repository wie folgt definiert:
$ git remote add origin git@github.com:schacon/simplegit-progit.git
It adds a section to your .git/config
file, specifying the name of the remote (origin
), the URL of the remote repository, and the refspec for fetching:
Das fügt eine Sektion in deine .git/config
Datei hinzu, die deinen lokalen Namen des externen Repositories (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/*
The format of the refspec is an optional +
, followed by <src>:<dst>
, where <src>
is the pattern for references on the remote side and <dst>
is where those references will be written locally. The +
tells Git to update the reference even if it isn’t a fast-forward.
Das Format der Refspec besteht aus einem optionalen +
gefolgt von <quelle>:<ziel>
, wobei <quelle>
ein Pattern 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.
In the default case that is automatically written by a git remote add
command, Git fetches all the references under refs/heads/
on the server and writes them to refs/remotes/origin/
locally. So, if there is a master
branch on the server, you can access the log of that branch locally via
Der Standard, der von git remote add
automatisch eingerichtet wird, besteht darin, daß Git austomatisch alle Referenzen unter refs/heads/
vom Server holt und sie lokal nach refs/remotes/origin
speichert. D.h., wenn es auf dem Server einen master
Branch 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
They’re all equivalent, because Git expands each of them to refs/remotes/origin/master
.
Diese Varianten sind allesamt äquivalent, weil Git sie jeweils zu refs/remotes/origin/master
vervollständigt.
If you want Git instead to pull down only the master
branch each time, and not every other branch on the remote server, you can change the fetch line to
Wenn du statt dessen willst, daß Git jeweils nur den master
Branch 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
This is just the default refspec for git fetch
for that remote. If you want to do something one time, you can specify the refspec on the command line, too. To pull the master
branch on the remote down to origin/mymaster
locally, you can run
Dies ist allerdings lediglich der Default Refspec Wert und du kannst ihn auf der Kommandozeile jederzeit überschreiben. Z.B. um nur master
branch vom Server lokal als origin/mymaster
zu speichern, kannst du folgendes ausführen:
$ git fetch origin master:refs/remotes/origin/mymaster
You can also specify multiple refspecs. On the command line, you can pull down several branches like so:
Du kannst auch mehrere Refspecs gleichzeitig spezifizieren. Z.B.:
$ 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 this case, the master branch pull was rejected because it wasn’t a fast-forward reference. You can override that by specifying the +
in front of the refspec.
I diesem Fall wurde ein Pull zurückgewiesen (xxx ist das nicht nur ein fetch? xxx), weil der Branch nicht mit einem simplen fast-forward aktualisiert werden konnte. Du kannst einen Merge erzwingen, indem du der Refspec ein +
voranstellst.
You can also specify multiple refspecs for fetching in your configuration file. If you want to always fetch the master and experiment branches, add two lines:
Du kannst außerdem natürlich auch mehrere Refspecs in deiner Konfiguration spezifizieren. Wenn du z.B. immer die master
und experiment
Branches 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
You can’t use partial globs in the pattern, so this would be invalid:
Du kannst keine partiellen Glob Patterns verwenden, d.h. folgendes wäre ungültig:
fetch = +refs/heads/qa*:refs/remotes/origin/qa*
However, you can use namespacing to accomplish something like that. If you have a QA team that pushes a series of branches, and you want to get the master branch and any of the QA team’s branches but nothing else, you can use a config section like this:
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 master Branch 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/*
If you have a complex workflow process that has a QA team pushing branches, developers pushing branches, and integration teams pushing and collaborating on remote branches, you can namespace them easily this way.
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.
Pushing Refspecs
Refspecs pushen
It’s nice that you can fetch namespaced references that way, but how does the QA team get their branches into a qa/
namespace in the first place? You accomplish that by using refspecs to push.
Wie aber legt das QA Team die Branches im qa/
Namensraum ab? Das geht, indem man mit einer Refspec pusht.
If the QA team wants to push their master
branch to qa/master
on the remote server, they can run
Wenn das QA Team seinen master
Branch in einem externen Repository als qa/master
speichern will, kann es das wie folgt tun:
$ git push origin master:refs/heads/qa/master
If they want Git to do that automatically each time they run git push origin
, they can add a push
value to their config file:
Um Git so zu konfigurieren, daß 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
Again, this will cause a git push origin
to push the local master
branch to the remote qa/master
branch by default.
Auf diese Weise wird git push origin
den lokalen Branch master
als qa/master
auf dem origin
Server speichern.
Deleting References
Referenzen löschen
You can also use the refspec to delete references from the remote server by running something like this:
Man kann Refspecs außerdem verwenden, um Referenzen aus einem externen Repository zu löschen:
$ git push origin :topic
Because the refspec is <src>:<dst>
, by leaving off the <src>
part, this basically says to make the topic branch on the remote nothing, which deletes it.
Das Refspec Format ist <quelle>:<ziel>
. Wenn man den <ziel>
Teil wegläßt, dann heißt das im obigen Beispiel, daß man den topic
Branch auf dem origin
Server auf “nichts” setzt, d.h. also löscht.