Git
Chapters ▾ 2nd Edition

10.5 Git Binnenwerk - De Refspec

De Refspec

In dit hele boek hebben we eenvoudige verbanden (mappings) gebruikt tussen remote branches naar lokale referenties, maar ze kunnen veel complexer zijn. Stel dat je een remote toevoegt op deze manier:

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

Dit voegt een sectie toe aan je .git/config bestand, waarbij de naam van de remote (origin) wordt opgegeven, de URL van de remote repository en de refspec foor het fetchen:

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

Het formaat van de refspec is een optionele +, gevolgd door <src>:<dst>, waar `<src> het patroon is voor referenties aan de remote kant, en <dst> de plaats is waar deze referenties lokaal zullen worden weggeschreven. De + draagt Git op om de referenties bij te werken zelfs als het geen fast-forward is.

In het standaard geval dat wordt automatisch geschreven door een git remote add commando, zal Git alle referenties onder refs/heads op de server fetchen en schrijft ze lokaal naar refs/remotes/origin. Dus, als er een master branch op de server is, kan je de log van deze branch benaderen via

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

Dit is allemaal gelijkwaardig, omdat Git elk van deze uitwerkt tot refs/remotes/origin/master.

Als je in plaats hiervan Git alleen de master branch wilt laten pullen, en niet elke andere branch op de remote server, kan je de fetch regel wijzigen in

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

Dit is gewoon de standaard refspec voor git fetch naar die remote. Als je iets maar eenmalig wilt doen, kan je de refspec ook op de command regel opgeven. Om de master branch te pullen van de remote naar lokaal origin/mymaster, kan je dit aanroepen

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

Je kunt ook meerdere refspecs opgeven. Op de commando regel kan je een aantal branches als volgt pullen:

$ 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 dit geval wordt de pull van de master branch geweigerd omdat het geen fast-forward referentie was. Je kunt dat overschrijven door een + voor de refspec op te geven.

Je kunt ook meerdere respecs voor fetchen aangeven in je configuratie bestand. Als je altijd de master en experiment branches wilt fetchen, voeg je twee regels toe:

[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

Je kunt niet gedeeltelijke globs in het patroon opgeven, dus dit zou ongeldig zijn:

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

Echter, je kunt naamsruimten (namespaces) of directories opgeven om zoiets voor elkaar te krijgen. Als je een QA team hebt die een reeks van branches pushed, en je wilt de master branch verkrijgen en alle branches van het QA team en niets anders, kan je een configuratie instelling als deze gebruiken:

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

Als je een complexe workflow proces hebt waarbij een QA team branches pushed, waarbij ontwikkelaar branches pushen en integratie teams die pushen naar en samenwerken op remote branches, kan je ze eenvoudig namespaces toewijzen op deze manier.

Refspecs pushen

Het is leuk dat je namespaced referenties op deze manier kunt fetchen, maar hoe krijgt het QA team om te beginnen hun branches in een qa/ namespace? Je krijgt dit voor eklaar door refspecs te gebruiken om te pushen.

Als het QA team hun master branch naar qa/master op de remote server wil pushen, kunnen ze dit aanroepen

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

Als ze willen dat Git dit elke keer automatisch doet als ze git push origin aanroepen, kunnen ze een push waarde aan hun configuratie bestand toevoegen:

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

Nogmaals, dit zal ervoor zorgen dat een git push origin de lokale master branch standaard naar de remote qa/master branch pushed.

References verwijderen

Je kunt de refspec ook gebruiken om referenties te verwijderen van de remote server door iets als dit aan te roepen:

$ git push origin :topic

Omdat de refspec <src>:<dst> is zal, door het weglaten van het <src> gedeelte, dit eigenlijk zeggen dat de topic branch van de remote niets moet worden, waarmee het wordt verwijderd.