Git
Chapters ▾ 2nd Edition

10.5 Git на ниско ниво - Refspec спецификации

Refspec спецификации

В книгата дотук използвахме просто съпоставяне от отдалечени клонове към локални референции, но те могат да бъдат и по-сложни. Допускаме, че сте следвали последните няколко секции и сте създали малко Git хранилище, сега искате да добавите remote към него:

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

Изпълнението на командата отгоре добавя секция във файла .git/config, която указва името на този remote (origin), URL-а на отдалеченото хранилище и refspec спецификацията, която да се използва за изтегляне:

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

Форматът е символът + (който е опция), последван от <src>:<dst>, където <src> е израз за референциите от отдалечената страна на връзката и <dst> указва къде тези референции ще се проследяват локално. Символът + казва на Git да обновява референцията дори, когато тя не е fast-forward.

В случаите по подразбиране, това се записва автоматично от командата git remote add origin, Git издърпва всички референции от refs/heads/ на сървъра и ги записва в refs/remotes/origin/ локално. Ако на сървъра има master клон, можете да получите достъп до историята му локално с коя да е от следните команди:

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

Те са еквивалентни, защото Git ги разширява до refs/remotes/origin/master.

Ако искате Git да изтегля само master клона всеки път, а другите не, можете да промените fetch реда така:

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

Това е точно подразбиращата се refspec спецификация за git fetch за този remote. Ако искате да правите само еднократно изтегляне, можете да укажете специфичната refspec спецификация също и от командния ред. За да изтеглите клона master от сървъра локално в origin/mymaster, може да изпълните:

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

Може да указвате и множество refspecs. От командния ред изтегляте няколко клона така:

$ 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

В този случай, изтеглянето на master клона беше отказано, защото той не е посочен като fast-forward референция. Може да преодолеете това със символа + преди съответната refspec.

Може да укажете множество refspecs за издърпване и в конфигурационния файл. Ако винаги искате да теглите клоновете master и experiment от origin сървъра, добавете два реда:

[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

Не може да използвате частични globs в изразите, следното ще е невалидно:

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

Обаче можете да използвате namespaces (или директории) за да постигнете нещо подобно. Ако имате QA екип, който публикува серии от клонове и желаете да получавате клона master, всеки от QA клоновете и нищо друго, използвайте подобна конфигурационна секция:

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

Ако сте в сложен работен процес, при който има QA екип, разработчици и интеграционни екипи, които публикуват и сътрудничат по отдалечени клонове, можете по този начин по-лесно да ги поставяте в съответни namespaces.

Публикуване на Refspecs

Добре е, че можете да издъпвате namespaced референции по този начин, но как QA екипа поставя клоновете си в qa/ namespace на първо време? Това се прави с помощта на push refspecs спецификации.

Ако QA екипът иска да публикува техния master клон в qa/master на сървъра, биха могли да изпълнят

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

Ако искат Git да прави това автоматично всеки път при git push origin, могат да добавят push елемент в конфигурационния си файл:

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

Така при git push origin локалният master клон ще се публикува в отдалечения qa/master по подразбиране.

Изтриване на референции

Можете също да използвате refspec за да изтривате референции от отдалечен сървър така:

$ git push origin :topic

Понеже спецификацията е във формат <src>:<dst>, пропускането на <src> частта ще направи така, че topic клонът в сървъра да е нищо — което ефективно ще го изтрие.

Или може да използвате по-новия синтаксис (след Git v1.7.0):

$ git push origin --delete topic