-
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 命令
3.5 Git 分支 - 遠端分支
遠端分支
遠端參考是遠端儲存庫中的參考(指標),包括分支、標籤等等。 您可以使用 git ls-remote <remote>
顯式地取得完整的遠端參考清單,或使用 git remote show <remote>
取得遠端分支以及更多資訊。 不過,更常見的方式是利用遠端追蹤分支。
遠端追蹤分支是對遠端分支狀態的參考。 它們是您無法移動的本機參考; 每當您進行任何網路通訊時,Git 會為您移動它們,以確保它們準確地代表遠端儲存庫的狀態。 將它們視為書籤,提醒您上次連線到遠端儲存庫時,它們的分支在哪裡。
遠端追蹤分支名稱採用 <remote>/<branch>
的形式。 例如,如果您想查看上次與 origin
遠端通訊時,master
分支的樣子,您會檢查 origin/master
分支。 如果您與夥伴合作處理一個問題,他們推送了 iss53
分支,您可能會擁有自己的本機 iss53
分支,但是伺服器上的分支將由遠端追蹤分支 origin/iss53
表示。
這可能有點令人困惑,讓我們來看一個例子。 假設您在網路上的 git.ourcompany.com
有一個 Git 伺服器。 如果您從這裡複製,Git 的 clone
命令會自動將其命名為 origin
,下載所有資料,建立一個指向其 master
分支所在位置的指標,並在本地將其命名為 origin/master
。 Git 也會給您自己的本機 master
分支,從與 origin 的 master
分支相同的位置開始,以便您有所依據。
注意
|
「origin」並非特殊
就像分支名稱「master」在 Git 中沒有任何特殊含義一樣,「origin」也沒有。 雖然「master」是您執行 |

如果您在本機 master
分支上進行一些工作,同時其他人推送至 git.ourcompany.com
並更新其 master
分支,那麼您的歷史記錄會以不同的方式前進。 此外,只要您與 origin
伺服器保持斷線,您的 origin/master
指標就不會移動。

要將您的工作與指定的遠端同步,您需要執行 git fetch <remote>
命令(在我們的例子中是 git fetch origin
)。這個命令會查詢「origin」伺服器是哪個(在這個例子中,它是 git.ourcompany.com
),從該伺服器擷取您尚未擁有的任何資料,並更新您的本機資料庫,將您的 origin/master
指標移動到新的、更為最新的位置。

git fetch
更新您的遠端追蹤分支為了示範擁有多個遠端伺服器,以及這些遠端專案的遠端分支看起來如何,讓我們假設您還有另一個內部 Git 伺服器,僅供您的某個衝刺團隊進行開發使用。此伺服器位於 git.team1.ourcompany.com
。您可以透過執行 git remote add
命令,將其新增為您目前正在處理的專案的新遠端參考,如同我們在Git 基礎中所介紹的。將此遠端命名為 teamone
,這將是該整個 URL 的簡稱。

現在,您可以執行 git fetch teamone
來擷取遠端 teamone
伺服器上您尚未擁有的所有內容。因為該伺服器擁有的資料是您目前 origin
伺服器所擁有的資料的子集,所以 Git 不會擷取任何資料,但會設定一個名為 teamone/master
的遠端追蹤分支,指向 teamone
的 master
分支所指向的 commit。

teamone/master
的遠端追蹤分支推送
當您想要與世界分享一個分支時,您需要將其推送到您具有寫入權限的遠端。您的本機分支不會自動同步到您寫入的遠端 — 您必須明確地推送您想要分享的分支。這樣一來,您可以使用私有分支來處理您不想分享的工作,並且只推送您想要協作的主題分支。
如果您有一個名為 serverfix
的分支,並且想要與他人協同工作,您可以像推送您的第一個分支一樣將其推送上去。執行 git push <remote> <branch>
$ git push origin serverfix
Counting objects: 24, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (24/24), 1.91 KiB | 0 bytes/s, done.
Total 24 (delta 2), reused 0 (delta 0)
To https://github.com/schacon/simplegit
* [new branch] serverfix -> serverfix
這是一個簡寫。Git 會自動將 serverfix
分支名稱展開為 refs/heads/serverfix:refs/heads/serverfix
,這意味著,「將我的 serverfix
本機分支推送上去,以更新遠端的 serverfix
分支。」我們將在Git 內部原理中詳細介紹 refs/heads/
的部分,但您通常可以省略它。您也可以執行 git push origin serverfix:serverfix
,這會執行相同的操作 — 它表示「取得我的 serverfix 並使其成為遠端的 serverfix」。您可以使用這種格式將本機分支推送到名稱不同的遠端分支。如果您不希望遠端上的分支被稱為 serverfix
,您可以改為執行 git push origin serverfix:awesomebranch
,將您的本機 serverfix
分支推送到遠端專案上的 awesomebranch
分支。
注意
|
不要每次都輸入您的密碼
如果您使用 HTTPS URL 來推送,Git 伺服器會要求您輸入使用者名稱和密碼進行身份驗證。預設情況下,它會在終端機上提示您輸入此資訊,以便伺服器可以判斷您是否被允許推送。 如果您不想每次推送都輸入密碼,您可以設定「憑證快取」。最簡單的方法是將其在記憶體中保留幾分鐘,您可以透過執行 如需更多關於可用憑證快取選項的資訊,請參閱憑證儲存。 |
下次您的合作者從伺服器擷取時,他們會獲得一個參考,指出伺服器版本的 serverfix
位於遠端分支 origin/serverfix
下方。
$ git fetch origin
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://github.com/schacon/simplegit
* [new branch] serverfix -> origin/serverfix
重要的是要注意,當您執行擷取,帶下新的遠端追蹤分支時,您不會自動擁有它們的本機、可編輯副本。換句話說,在這個例子中,您沒有新的 serverfix
分支 — 您只有一個無法修改的 origin/serverfix
指標。
要將此工作合併到您目前的工作分支中,您可以執行 git merge origin/serverfix
。如果您想要一個可以工作的自己的 serverfix
分支,您可以將其建立在您的遠端追蹤分支之上
$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'
這會給您一個可以工作的本機分支,它從 origin/serverfix
所在的位置開始。
追蹤分支
從遠端追蹤分支檢出本機分支會自動建立所謂的「追蹤分支」(而它追蹤的分支稱為「上游分支」)。追蹤分支是與遠端分支有直接關係的本機分支。如果您在追蹤分支上並輸入 git pull
,Git 會自動知道要從哪個伺服器擷取以及要合併哪個分支。
當您複製一個儲存庫時,它通常會自動建立一個追蹤 origin/master
的 master
分支。但是,如果您願意,您可以設定其他追蹤分支 — 追蹤其他遠端分支的分支,或者不追蹤 master
分支的分支。簡單的情況是您剛才看到的範例,執行 git checkout -b <branch> <remote>/<branch>
。這是一個很常見的操作,因此 Git 提供了 --track
簡寫
$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'
事實上,這是如此常見,以至於對這個簡寫還有一個簡寫。如果您嘗試檢出的分支名稱 (a) 不存在,並且 (b) 與只有一個遠端上的名稱完全匹配,Git 會為您建立一個追蹤分支
$ git checkout serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'
要設定一個與遠端分支名稱不同的本機分支,您可以輕鬆地使用第一個版本和不同的本機分支名稱
$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'
現在,您的本機分支 sf
將自動從 origin/serverfix
拉取。
如果您已經有一個本機分支,並且想要將其設定為您剛才拉取的遠端分支,或者想要變更您正在追蹤的上游分支,您可以使用 git branch
的 -u
或 --set-upstream-to
選項,隨時明確地設定它。
$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
注意
|
上游簡寫
當您設定了追蹤分支時,您可以使用 |
如果您想查看您設定了哪些追蹤分支,您可以使用 git branch
的 -vv
選項。這將列出您的本機分支,並提供更多資訊,包括每個分支正在追蹤的內容,以及您的本機分支是否領先、落後或同時領先和落後。
$ git branch -vv
iss53 7e424c3 [origin/iss53: ahead 2] Add forgotten brackets
master 1ae2a45 [origin/master] Deploy index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] This should do it
testing 5ea463a Try something new
因此,在這裡我們可以發現我們的 iss53
分支正在追蹤 origin/iss53
,並且「領先」了兩個 commit,這意味著我們在本機上有兩個尚未推送到伺服器的 commit。我們還可以發現我們的 master
分支正在追蹤 origin/master
,並且是最新的。接下來,我們可以發現我們的 serverfix
分支正在追蹤我們 teamone
伺服器上的 server-fix-good
分支,並且領先三個 commit,落後一個 commit,這意味著伺服器上有一個我們尚未合併的 commit,並且在本機上有三個我們尚未推送的 commit。最後,我們可以發現我們的 testing
分支沒有追蹤任何遠端分支。
重要的是要注意,這些數字僅是自您上次從每個伺服器擷取以來的數字。此命令不會連線到伺服器,它會告訴您它從這些伺服器在本機快取的內容。如果您想要完全最新的領先和落後數字,您需要在執行此命令之前從所有遠端擷取。您可以這樣做
$ git fetch --all; git branch -vv
拉取
雖然 git fetch
命令會擷取伺服器上您尚未擁有的所有變更,但它根本不會修改您的工作目錄。它只會為您取得資料,並讓您自行合併。但是,有一個命令叫做 git pull
,它本質上是在大多數情況下緊接著 git merge
的 git fetch
。如果您如上一節所示設定了追蹤分支,無論是透過明確設定還是由 clone
或 checkout
命令為您建立的,git pull
都會查詢您目前分支正在追蹤的伺服器和分支,從該伺服器擷取,然後嘗試合併該遠端分支。
通常,最好只是明確地使用 fetch
和 merge
命令,因為 git pull
的神奇之處通常會讓人感到困惑。
刪除遠端分支
假設您已完成遠端分支 — 例如您和您的合作者已完成某個功能,並將其合併到您遠端的 master
分支(或您的穩定程式碼所在的任何分支)。您可以使用 git push
的 --delete
選項來刪除遠端分支。如果您想要從伺服器刪除您的 serverfix
分支,請執行以下操作
$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
- [deleted] serverfix
基本上,所有這一切都是從伺服器中移除指標。Git 伺服器通常會將資料保留在那裡一段時間,直到執行垃圾收集,因此如果意外刪除,通常很容易恢復。