-
1. 起步
-
2. Git 基礎
-
3. Git 分支
-
4. 伺服器上的 Git
- 4.1 協議
- 4.2 在伺服器上部署 Git
- 4.3 生成 SSH 公鑰
- 4.4 架設伺服器
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 第三方託管服務
- 4.10 小結
-
5. 分散式 Git
-
A1. 附錄 A: Git 在其他環境
- A1.1 圖形介面
- A1.2 Visual Studio 中的 Git
- A1.3 Visual Studio Code 中的 Git
- A1.4 IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git
- A1.5 Sublime Text 中的 Git
- A1.6 Bash 中的 Git
- A1.7 Zsh 中的 Git
- A1.8 PowerShell 中的 Git
- A1.9 小結
-
A2. 附錄 B: 在應用程式中嵌入 Git
-
A3. 附錄 C: 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 即使它不是一個快進(fast-forward)也要更新引用。
預設情況下,當執行 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
遠端倉庫抓取 master
和 experiment
分支,新增兩行
[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 開始,你可以在模式中使用部分萬用字元(globs)來匹配多個分支,因此這也可以工作
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