Git
Chapters ▾ 2nd Edition

10.5 Git Internals - The Refspec

The Refspec

Throughout this book, we’ve used simple mappings from remote branches to local references, but they can be more complex. Řekněme, že přidáte například tento vzdálený repozitář:

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

Přidáte tím novou část do souboru .git/config, určíte název vzdáleného serveru (origin), URL vzdáleného repozitáře a refspec pro vyzvednutí dat:

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*

Refspec má následující formát: fakultativní znak +, za nímž následuje <src>:<dst>, kde <src> je vzor pro referenci na straně vzdáleného serveru a <dst> je lokální umístění, kam mají být tyto reference zapsány. The + tells Git to update the reference even if it isn’t a fast-forward.

Ve výchozím případě, který se automaticky zapisuje příkazem git remote add, Git vyzvedne všechny reference z adresáře refs/heads/ na serveru a zapíše je do lokálního adresáře refs/remotes/origin/. Je-li tedy na serveru hlavní větev master, lokálně lze získat přístup k jejímu logu některým z příkazů:

$ 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.

Pokud ale raději chcete, aby Git pokaždé stáhl pouze větev master a nestahoval žádné jiné větve na vzdáleném serveru, změňte řádek příkazu fetch na:

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

Toto je výchozí vzorec refspec pro příkaz git fetch pro tento vzdálený server. Chcete-li nějakou akci provést pouze jednou, můžete použít refspec také na příkazovém řádku. Chcete-li stáhnout větev master ze vzdáleného serveru do lokálního adresáře origin/mymaster, můžete zadat příkaz:

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

Použít lze také kombinaci několika vzorců refspec. Několik větví můžete přímo z příkazového řádku stáhnout například takto:

$ 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. Odmítnutí serveru můžete potlačit zadáním znaku + před vzorec refspec.

V konfiguračním souboru můžete také použít více vzorců refspec pro vyzvedávání dat. If you want to always fetch the master and experiment branches, add two lines:

[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

You can’t use partial globs in the pattern, so this would be invalid:

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

However, you can use namespaces (or directories) 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:

[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/*

Jestliže používáte komplexní pracovní proces, kdy QA tým odesílá větve, vývojáři odesílají větve a integrační týmy odesílají větve a spolupracují na nich, můžete takto jednoduše využít možností, jež vám jmenný prostor nabízí.

Pushing Refspecs

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? Tady vám při odesílání větví pomůže vzorec refspec.

Chce-li QA tým odeslat větev master do adresáře qa/master na vzdáleném serveru, může použít příkaz:

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

Chcete-li, aby toto Git provedl automaticky pokaždé, když spustíte příkaz git push origin, můžete do konfiguračního souboru vložit hodnotu push:

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*
	push = refs/heads/master:refs/heads/qa/master

Touto hodnotou zajistíte, že bude příkaz git push origin odesílat lokální větev master do vzdálené větve qa/master.

Mazání referencí

Vzorce refspec můžete využít také k mazání referencí ze vzdáleného serveru. Spustit lze například příkaz následujícího znění:

$ 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.