Git
Chapters ▾ 2nd Edition

10.5 Git iznutra - Refspek

Refspek

Kroz ovu knjigu smo koristili jednstavna mapiranja iz udaljenih grana na lokalne reference, ali ona mogu biti i složenija. Pretpostavimo da ovako dodate udaljenu referencu:

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

Ovime dodajete odeljak u datoteci .git/config, određujete ime udaljene reference (origin), URL udaljenog repozitorijuma i refspek (referentnu specifikaciju) za pribavljanje:

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

Format refspeka je opcioni + za kojim sledi <src>:<dst>, gde je <src> šablon za reference na udaljenoj strani, a <dst> je gde će se te reference zapisati lokalno. Znak + govori Gitu da ažurira referencu čak i ako nije u pitanju motanje unapred.

U podrazumevanom slučaju koje se automatski upisuje komandom git remote add, Git pribavlja sve reference pod refs/heads/ na serveru i piše ih u refs/remotes/origin/ lokalno. Dakle, ako je grana master na serveru, možete da pristupite logu te grane lokalno na sledeći način.

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

Svi su ekvivalentni, jer ih Git proširuje na refs/remotes/origin/master.

Ako želite da Git umesto toga dovuče samo granu master svaki put, a ne svaku drugu granu sa udaljenog serevra, možete da promeniti liniju za pribavljanje na sledeće.

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

Ovo je samo pdorazumevani refspek za git fetch za tu udaljenu referencu. Ako želite da uradite nešto jednom, možete da specifirane refspek i preko komandne linije. Da biste dovukli

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

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

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

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:

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

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.

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? You accomplish that by using refspecs to push.

If the QA team wants to push their master branch to qa/master on the remote server, they can run

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

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	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.

Deleting References

You can also use the refspec to delete references from the remote server by running something like this:

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