Git
章節 ▾ 第二版

10.5 Git 內部 - Refspec

Refspec

在本書中,我們使用了從遠端分支到本地參考的簡單映射,但它們可以更複雜。假設您跟著前幾個章節操作,建立了一個小的本地 Git 儲存庫,現在想在其中新增一個遠端

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

執行上述命令會在儲存庫的 .git/config 檔案中新增一個區段,指定遠端的名稱 (origin)、遠端儲存庫的 URL,以及用於提取的refspec

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

refspec 的格式為:首先,一個可選的 +,後面跟著 <src>:<dst>,其中 <src> 是遠端參考的模式,<dst> 是這些參考在本地追蹤的位置。+ 告訴 Git 更新參考,即使它不是快速轉發。

git remote add origin 命令自動寫入的預設情況下,Git 會提取伺服器上 refs/heads/ 下的所有參考,並將它們寫入本地的 refs/remotes/origin/。因此,如果伺服器上有一個 master 分支,您可以透過以下任何一種方式在本地存取該分支的日誌

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

它們都是等效的,因為 Git 會將它們都擴展為 refs/remotes/origin/master

如果您希望 Git 每次只提取 master 分支,而不是遠端伺服器上的所有其他分支,您可以更改提取行以僅參考該分支

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

這只是該遠端 git fetch 的預設 refspec。如果您想要進行一次性提取,您也可以在命令列上指定特定的 refspec。若要將遠端的 master 分支提取到本地的 origin/mymaster,您可以執行

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

您也可以指定多個 refspec。在命令列上,您可以像這樣提取多個分支

$ 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

在這種情況下,由於 master 分支未列為快速轉發參考,因此提取被拒絕。您可以透過在 refspec 前面指定 + 來覆寫該行為。

您也可以在您的設定檔中指定多個用於提取的 refspec。如果您希望始終從 origin 遠端提取 masterexperiment 分支,請新增兩行

[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

從 Git 2.6.0 開始,您可以在模式中使用部分全域模式來匹配多個分支,因此這將會有效

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

更棒的是,您可以使用命名空間(或目錄)來實現相同的效果,並具有更高的結構性。如果您有一個 QA 團隊會推送一系列分支,並且您想要取得 master 分支和任何 QA 團隊的分支,但不要其他分支,您可以使用如下的配置區段:

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

如果您有一個複雜的工作流程,其中包含 QA 團隊推送分支、開發人員推送分支,以及整合團隊推送和協作遠端分支,您可以輕鬆地用這種方式進行命名空間管理。

推送 Refspec

能夠以這種方式獲取命名空間的參考是很棒,但 QA 團隊如何首先將他們的分支放入 qa/ 命名空間中呢?您可以使用 refspec 來推送來完成此操作。

如果 QA 團隊想要將他們的 master 分支推送到遠端伺服器上的 qa/master,他們可以執行:

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

如果他們希望 Git 每次執行 git push origin 時自動執行此操作,他們可以在其設定檔中添加一個 push 值:

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

同樣,這將導致 git push origin 預設將本機 master 分支推送到遠端的 qa/master 分支。

注意

您不能使用 refspec 從一個儲存庫提取並推送到另一個儲存庫。如需這樣做的範例,請參閱保持您的 GitHub 公開儲存庫為最新狀態

刪除參考

您也可以使用 refspec 從遠端伺服器刪除參考,方法是執行如下指令:

$ git push origin :topic

因為 refspec 是 <src>:<dst>,所以省略 <src> 部分基本上表示將遠端的 topic 分支設定為無,這樣就會刪除它。

或者您可以使用較新的語法 (自 Git v1.7.0 起可用):

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