Git 🌙
Chapters ▾ 2nd Edition

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

От Git 2.6.0 може да използвате частични 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 за да теглите от едно хранилище и да изпращте към друго. За пример как би могло да стане това, погледнете Актуализиране на вашето публично GitHub хранилище.

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

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

$ git push origin :topic

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

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

$ git push origin --delete topic
scroll-to-top