De refspec
Door dit boek heen heb je eenvoudige verwijzingen van remote branches naar lokale referenties gebruikt; maar ze kunnen complexer zijn. Stel dat je een remote zoals dit toevoegt:
$ git remote add origin git@github.com:schacon/simplegit-progit.git
Dit voegt een sectie aan je .git/config
bestand toe, wat de naam van de remote (origin
) specificeert, de URL van de remote repository, en de refspec die nodig is om te fetchen:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
Het formaat van de refspec is een optionele +
, gevolgd door <src>:<dst>
, waarbij <src>
het patroon voor referenties aan de remote kant is, en <dst>
is de locatie waar die referenties lokaal geschreven worden. De +
verteld Git om de referentie zelfs te vernieuwen als het geen fast-forward is.
In het standaard geval dat automatisch geschreven wordt door een git remote add
commando, haalt Git alle referenties onder refs/heads/
van de server en schrijft ze lokaal naar refs/remotes/origin/
. Dus als er een master
branch op de server bestaat, kun je de log van die branch lokaal benaderen via
$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master
Ze zijn allemaal gelijk, omdat Git elk expandeert naar refs/remotes/origin/master
.
Als je wilt dat Git alleen de master
branch pulled, en niet alle andere branches op de remote server, kun je de fetch regel veranderen in
fetch = +refs/heads/master:refs/remotes/origin/master
Dit is alleen de standaard refspec voor git fetch
voor die remote. Als je iets alleen eenmalig wilt doen, kun je de refspec ook op de commandoregel specificeren. Om de master
branch op de remote naar de lokale origin/mymaster
te pullen, kun je dit uitvoeren
$ git fetch origin master:refs/remotes/origin/mymaster
Je kunt ook meerdere refspecs specificeren. Met de commandoregel kun je meerdere branches op deze manier 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 is. Je kunt dat teniet doen door de +
voor de refspec te zetten.
Je kun ook meerdere refspecs voor het fetchen specificeren in je configuratie bestand. Als je altijd de master en experiment branches wilt fetchen, voeg dan twee regels toe:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/experiment:refs/remotes/origin/experiment
Je kunt geen gedeeltelijke globs in het patroon gebruiken, dus het volgende zou ongeldig zijn:
fetch = +refs/heads/qa*:refs/remotes/origin/qa*
Maar je kunt wel naamruimtes gebruiken om zoiets voor elkaar te krijgen. Als je een QA team hebt dat naar een serie branches pushed, en je wilt de master branch en alle QA team branches hebben, maar niets anders, kun je een configuratie sectie zoals dit gebruiken:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
Als je een ingewikkeld werkproces hebt waarbij het QA team branches pushed, ontwikkelaars branches pushen, en integratie teams pushen en samenwerken op remote branches, kun je ze op deze manier eenvoudig in naamruimten stoppen.
Refspecs pushen
Het is fijn dat je op die manier referenties in naamruimten kunt fetchen, maar hoe krijgt het QA team in de eerste plaats al hun branches in een qa/
naamruimte? Je krijgt dat voor elkaar door refspecs te gebruiken om mee te pushen.
Als het QA team hun master
branch naar qa/master
op de remote server wil pushen, kunnen ze dit uitvoeren
$ git push origin master:refs/heads/qa/master
Als ze willen dat Git dat automatisch doet iedere keer als ze git push origin
uitvoeren, dan kunnen ze een push waarde aan hun configuratie bestand toevoegen:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/qa/master
Nogmaals, dit zal zorgen dat git push origin
de lokale master
branch standaard naar de remote qa/master
branch zal pushen.
Referenties verwijderen
Je kunt de refspec ook gebruiken om referenties te verwijderen van de remote server door zoiets als dit uit te voeren:
$ git push origin :topic
Omdat de refspec <src>:<dst>
is, verteld het weglaten van het <src>
gedeelte in feite dat de onderwerp branch op de remote niks is, wat het verwijderd.