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 even dat je met de paar laatste secties hebt meegedaan en een kleine lokale Git repository gemaakt hebt, en nu een remote eraan zou willen toevoegen:

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

Dit commando 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 die gebruikt moet worden voor het fetchen:

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

Het formaat van de refspec is, eerst, een optionele {plus}, 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 getrackt. De {plus} draagt Git op om de referenties bij te werken zelfs als het geen fast-forward is.

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

$ 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 zodat het alleen naar die branch wijst:

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

Dit is gewoon de standaard refspec voor git fetch naar die remote. Als je een eenmalige fetch wilt doen, kan je de refspec ook op de command regel opgeven. Om de master-branch te pullen van de remote naar een lokale 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 meerdere 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 niet als een fast-forward referentie was opgegeven. Je kunt dat overschrijven door een {plus} 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 pusht, en je wilt de master branch verkrijgen en alle branches van het QA team maar 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 pusht, waarbij ontwikkelaar branches pushen en integratie teams die pushen naar en samenwerken op remote branches, kan je ze op deze manier eenvoudig namespaces toewijzen.

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 elkaar 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 pusht.

Noot

Je kunt de refspec niet gebruiken om van de ene repository te fetchen en te pushen naar een andere. Voor een voorbeeld hoe dit wel te doen, zie Houd je GitHub openbare repository up-to-date.

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 zegt dit, door het weglaten van het <src> gedeelte, eigenlijk dat de topic branch van de remote niets moet worden, waarmee het wordt verwijderd.

Of je kunt de nieuwere syntax gebruiken (beschikbaar vanaf Git v1.7.0):

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