Chapters ▾ 2nd Edition

10.5 Git bakom kulisserna - Refspecen

Refspecen

Genom hela boken har vi använt enkla mappningar från fjärrgrenar till lokala referenser, men de kan också vara mer komplexa. Anta att du följde med i de senaste avsnitten och skapade ett litet lokalt Git‑kodförråd, och nu vill lägga till en fjärr:

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

När du kör kommandot ovan läggs en sektion till i kodförrådets .git/config‑fil som anger fjärrkodförrådets namn (origin), URL:en till fjärrkodförrådet och den refspec som ska användas vid uppdatering:

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

Formatet för refspecen är först ett valfritt +, följt av <src>:<dst>, där <src> är mönstret för referenser på fjärrsidan och <dst> anger var dessa referenser ska spåras lokalt. + talar om för Git att uppdatera referensen även om det inte är en fast‑forward.

I standardfallet som automatiskt skrivs av kommandot git remote add origin uppdaterar Git alla referenser under refs/heads/ på servern och skriver dem lokalt till refs/remotes/origin/. Så om det finns en gren master på servern kan du komma åt loggen för den grenen lokalt via något av följande:

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

Alla är likvärdiga, eftersom Git expanderar var och en av dem till refs/remotes/origin/master.

Om du i stället vill att Git bara ska uppdatera grenen master varje gång, och inte alla andra grenar på fjärrservern, kan du ändra uppdatering‑raden så att den bara pekar på den grenen:

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

Det här är standard‑refspecen för git fetch för det fjärrkodförrådet. Om du vill göra en engångsuppdatering kan du också ange den specifika refspecen på kommandoraden. För att uppdatera grenen master från fjärrkodförrådet till origin/mymaster lokalt kan du köra:

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

Du kan också ange flera refspecar. På kommandoraden kan du uppdatera flera grenar så här:

$ 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

I det här fallet nekades uppdateringen av grenen master eftersom den inte var listad som en fast‑forward‑referens. Du kan åsidosätta det genom att ange + framför refspecen.

Du kan också ange flera refspecar för uppdatering i din konfigurationsfil. Om du alltid vill uppdatera grenarna master och experiment från fjärrkodförrådet origin lägger du till två rader:

[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

Sedan Git 2.6.0 kan du använda delvisa globbar i mönstret för att matcha flera grenar, så detta fungerar:

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

Ännu bättre är att du kan använda namnrymder (eller kataloger) för att åstadkomma samma sak mer strukturerat. Om du har ett QA‑team som skickar upp en serie grenar och du vill få grenen master och QA‑teamets grenar men inget annat, kan du använda en konfigurationssektion som denna:

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

Om du har ett komplext arbetsflöde där ett QA‑team skickar upp grenar, utvecklare skickar upp grenar och integrationsteam skickar upp och samarbetar på fjärrgrenar kan du enkelt namnge dem på det här sättet.

Skicka refspecar

Det är trevligt att du kan uppdatera namnrymda referenser på det sättet, men hur får QA‑teamet in sina grenar i en qa/‑namnrymd från början? Det åstadkommer du genom att använda refspecar för att skicka.

Om QA‑teamet vill skicka sin gren master till qa/master på fjärrservern kan de göra så här:

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

Om de vill att Git automatiskt ska göra det varje gång de kör git push origin, kan de lägga till ett push‑värde i sin konfigurationsfil:

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

Det innebär också att git push origin som standard skickar upp den lokala grenen master till fjärrgrenen qa/master.

Notera

Du kan inte använda refspecen för att uppdatera från ett kodförråd och skicka till ett annat. För ett exempel på hur man gör det, se Håll ditt publika GitHub-kodförråd uppdaterat.

Radera referenser

Du kan också använda refspecen för att radera referenser från fjärrservern genom att köra något i den här stilen:

$ git push origin :topic

Eftersom refspecen är <src>:<dst> betyder det, genom att utelämna <src>‑delen, i praktiken att grenen topic i fjärrkodförrådet blir ingenting, vilket tar bort den.

Eller så kan du använda den nyare syntaxen (tillgänglig sedan Git v1.7.0):

$ git push origin --delete topic