5 Git 分支 - 远程分支
遠(yuǎn)程分支
遠(yuǎn)程引用是對(duì)遠(yuǎn)程倉庫的引用(指針),包括分支、標(biāo)簽等等。你可以通過 git ls-remote (remote) 來顯式地獲得遠(yuǎn)程引用的完整列表,或者通過 git remote show (remote) 獲得遠(yuǎn)程分支的更多信息。然而,一個(gè)更常見的做法是利用遠(yuǎn)程跟蹤分支。
遠(yuǎn)程跟蹤分支是遠(yuǎn)程分支狀態(tài)的引用。它們是你不能移動(dòng)的本地引用,當(dāng)你做任何網(wǎng)絡(luò)通信操作時(shí),它們會(huì)自動(dòng)移動(dòng)。遠(yuǎn)程跟蹤分支像是你上次連接到遠(yuǎn)程倉庫時(shí),那些分支所處狀態(tài)的書簽。
它們以 (remote)/(branch) 形式命名。例如,如果你想要看你最后一次與遠(yuǎn)程倉庫 origin 通信時(shí) master 分支的狀態(tài),你可以查看 origin/master 分支。你與同事合作解決一個(gè)問題并且他們推送了一個(gè) iss53 分支,你可能有自己的本地 iss53 分支;但是在服務(wù)器上的分支會(huì)指向 origin/iss53 的提交。
這可能有一點(diǎn)兒難以理解,讓我們來看一個(gè)例子。假設(shè)你的網(wǎng)絡(luò)里有一個(gè)在 git.ourcompany.com 的 Git 服務(wù)器。如果你從這里克隆,Git 的 clone 命令會(huì)為你自動(dòng)將其命名為 origin,拉取它的所有數(shù)據(jù),創(chuàng)建一個(gè)指向它的 master 分支的指針,并且在本地將其命名為 origin/master。Git 也會(huì)給你一個(gè)與 origin 的 master 分支在指向同一個(gè)地方的本地 master 分支,這樣你就有工作的基礎(chǔ)。
| Note | “origin” 并無特殊含義 遠(yuǎn)程倉庫名字 “origin” 與分支名字 “master” 一樣,在 Git 中并沒有任何特別的含義一樣。同時(shí) “master” 是當(dāng)你運(yùn)行 git init 時(shí)默認(rèn)的起始分支名字,原因僅僅是它的廣泛使用,“origin” 是當(dāng)你運(yùn)行 git clone 時(shí)默認(rèn)的遠(yuǎn)程倉庫名字。如果你運(yùn)行 git clone -o booyah,那么你默認(rèn)的遠(yuǎn)程分支名字將會(huì)是 booyah/master。 |
如果你在本地的 master 分支做了一些工作,然而在同一時(shí)間,其他人推送提交到 git.ourcompany.com 并更新了它的 master 分支,那么你的提交歷史將向不同的方向前進(jìn)。也許,只要你不與 origin 服務(wù)器連接,你的 origin/master 指針就不會(huì)移動(dòng)。
Figure 31. 本地與遠(yuǎn)程的工作可以分叉如果要同步你的工作,運(yùn)行 git fetch origin 命令。這個(gè)命令查找 “origin” 是哪一個(gè)服務(wù)器(在本例中,它是 git.ourcompany.com),從中抓取本地沒有的數(shù)據(jù),并且更新本地?cái)?shù)據(jù)庫,移動(dòng) origin/master 指針指向新的、更新后的位置。
Figure 32. git fetch 更新你的遠(yuǎn)程倉庫引用為了演示有多個(gè)遠(yuǎn)程倉庫與遠(yuǎn)程分支的情況,我們假定你有另一個(gè)內(nèi)部 Git 服務(wù)器,僅用于你的 sprint 小組的開發(fā)工作。這個(gè)服務(wù)器位于 git.team1.ourcompany.com。你可以運(yùn)行 git remote add 命令添加一個(gè)新的遠(yuǎn)程倉庫引用到當(dāng)前的項(xiàng)目,這個(gè)命令我們會(huì)在 Git 基礎(chǔ) 中詳細(xì)說明。將這個(gè)遠(yuǎn)程倉庫命名為 teamone,將其作為整個(gè) URL 的縮寫。
Figure 33. 添加另一個(gè)遠(yuǎn)程倉庫現(xiàn)在,可以運(yùn)行 git fetch teamone 來抓取遠(yuǎn)程倉庫 teamone 有而本地沒有的數(shù)據(jù)。因?yàn)槟桥_(tái)服務(wù)器上現(xiàn)有的數(shù)據(jù)是 origin 服務(wù)器上的一個(gè)子集,所以 Git 并不會(huì)抓取數(shù)據(jù)而是會(huì)設(shè)置遠(yuǎn)程跟蹤分支 teamone/master 指向 teamone 的 master 分支。
Figure 34. 遠(yuǎn)程跟蹤分支 teamone/master推送
當(dāng)你想要公開分享一個(gè)分支時(shí),需要將其推送到有寫入權(quán)限的遠(yuǎn)程倉庫上。本地的分支并不會(huì)自動(dòng)與遠(yuǎn)程倉庫同步 - 你必須顯式地推送想要分享的分支。這樣,你就可以把不愿意分享的內(nèi)容放到私人分支上,而將需要和別人協(xié)作的內(nèi)容推送到公開分支。
如果希望和別人一起在名為 serverfix 的分支上工作,你可以像推送第一個(gè)分支那樣推送它。運(yùn)行 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這里有些工作被簡(jiǎn)化了。Git 自動(dòng)將 serverfix 分支名字展開為 refs/heads/serverfix:refs/heads/serverfix,那意味著,“推送本地的 serverfix 分支來更新遠(yuǎn)程倉庫上的 serverfix 分支。”我們將會(huì)詳細(xì)學(xué)習(xí) Git 內(nèi)部原理 的 refs/heads/ 部分,但是現(xiàn)在可以先把它放在兒。你也可以運(yùn)行 git push origin serverfix:serverfix,它會(huì)做同樣的事 - 相當(dāng)于它說,“推送本地的 serverfix 分支,將其作為遠(yuǎn)程倉庫的 serverfix 分支”可以通過這種格式來推送本地分支到一個(gè)命名不相同的遠(yuǎn)程分支。如果并不想讓遠(yuǎn)程倉庫上的分支叫做 serverfix,可以運(yùn)行 git push origin serverfix:awesomebranch 來將本地的 serverfix 分支推送到遠(yuǎn)程倉庫上的 awesomebranch 分支。
| Note | 如何避免每次輸入密碼 如果你正在使用 HTTPS URL 來推送,Git 服務(wù)器會(huì)詢問用戶名與密碼。默認(rèn)情況下它會(huì)在終端中提示服務(wù)器是否允許你進(jìn)行推送。 如果不想在每一次推送時(shí)都輸入用戶名與密碼,你可以設(shè)置一個(gè) “credential cache”。最簡(jiǎn)單的方式就是將其保存在內(nèi)存中幾分鐘,可以簡(jiǎn)單地運(yùn)行 git config --global credential.helper cache 來設(shè)置它。 想要了解更多關(guān)于不同驗(yàn)證緩存的可用選項(xiàng),查看 憑證存儲(chǔ)。 |
下一次其他協(xié)作者從服務(wù)器上抓取數(shù)據(jù)時(shí),他們會(huì)在本地生成一個(gè)遠(yuǎn)程分支 origin/serverfix,指向服務(wù)器的 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要特別注意的一點(diǎn)是當(dāng)抓取到新的遠(yuǎn)程跟蹤分支時(shí),本地不會(huì)自動(dòng)生成一份可編輯的副本(拷貝)。換一句話說,這種情況下,不會(huì)有一個(gè)新的 serverfix 分支 - 只有一個(gè)不可以修改的 origin/serverfix 指針。
可以運(yùn)行 git merge origin/serverfix 將這些工作合并到當(dāng)前所在的分支。如果想要在自己的 serverfix 分支上工作,可以將其建立在遠(yuǎn)程跟蹤分支之上:
$ git checkout -b serverfix origin/serverfix Branch serverfix set up to track remote branch serverfix from origin. Switched to a new branch 'serverfix'這會(huì)給你一個(gè)用于工作的本地分支,并且起點(diǎn)位于 origin/serverfix。
跟蹤分支
從一個(gè)遠(yuǎn)程跟蹤分支檢出一個(gè)本地分支會(huì)自動(dòng)創(chuàng)建一個(gè)叫做 “跟蹤分支”(有時(shí)候也叫做 “上游分支”)。跟蹤分支是與遠(yuǎn)程分支有直接關(guān)系的本地分支。如果在一個(gè)跟蹤分支上輸入 git pull,Git 能自動(dòng)地識(shí)別去哪個(gè)服務(wù)器上抓取、合并到哪個(gè)分支。
當(dāng)克隆一個(gè)倉庫時(shí),它通常會(huì)自動(dòng)地創(chuàng)建一個(gè)跟蹤 origin/master 的 master 分支。然而,如果你愿意的話可以設(shè)置其他的跟蹤分支 - 其他遠(yuǎn)程倉庫上的跟蹤分支,或者不跟蹤 master 分支。最簡(jiǎn)單的就是之前看到的例子,運(yùn)行 git checkout -b [branch] [remotename]/[branch]。這是一個(gè)十分常用的操作所以 Git 提供了 --track 快捷方式:
$ git checkout --track origin/serverfix Branch serverfix set up to track remote branch serverfix from origin. Switched to a new branch 'serverfix'如果想要將本地分支與遠(yuǎn)程分支設(shè)置為不同名字,你可以輕松地增加一個(gè)不同名字的本地分支的上一個(gè)命令:
$ git checkout -b sf origin/serverfix Branch sf set up to track remote branch serverfix from origin. Switched to a new branch 'sf'現(xiàn)在,本地分支 sf 會(huì)自動(dòng)從 origin/serverfix 拉取。
設(shè)置已有的本地分支跟蹤一個(gè)剛剛拉取下來的遠(yuǎn)程分支,或者想要修改正在跟蹤的上游分支,你可以在任意時(shí)間使用 -u 或 --set-upstream-to 選項(xiàng)運(yùn)行 git branch 來顯式地設(shè)置。
$ git branch -u origin/serverfix Branch serverfix set up to track remote branch serverfix from origin.| Note | 上游快捷方式 當(dāng)設(shè)置好跟蹤分支后,可以通過 @{upstream} 或 @{u} 快捷方式來引用它。所以在 master 分支時(shí)并且它正在跟蹤 origin/master 時(shí),如果愿意的話可以使用 git merge @{u} 來取代 git merge origin/master。 |
如果想要查看設(shè)置的所有跟蹤分支,可以使用 git branch 的 -vv 選項(xiàng)。這會(huì)將所有的本地分支列出來并且包含更多的信息,如每一個(gè)分支正在跟蹤哪個(gè)遠(yuǎn)程分支與本地分支是否是領(lǐng)先、落后或是都有。
$ git branch -vviss53 7e424c3 [origin/iss53: ahead 2] forgot the bracketsmaster 1ae2a45 [origin/master] deploying index fix * serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do ittesting 5ea463a trying something new這里可以看到 iss53 分支正在跟蹤 origin/iss53 并且 “ahead” 是 2,意味著本地有兩個(gè)提交還沒有推送到服務(wù)器上。也能看到 master 分支正在跟蹤 origin/master 分支并且是最新的。接下來可以看到 serverfix 分支正在跟蹤 teamone 服務(wù)器上的 server-fix-good 分支并且領(lǐng)先 3 落后 1,意味著服務(wù)器上有一次提交還沒有合并入同時(shí)本地有三次提交還沒有推送。最后看到 testing 分支并沒有跟蹤任何遠(yuǎn)程分支。
需要重點(diǎn)注意的一點(diǎn)是這些數(shù)字的值來自于你從每個(gè)服務(wù)器上最后一次抓取的數(shù)據(jù)。這個(gè)命令并沒有連接服務(wù)器,它只會(huì)告訴你關(guān)于本地緩存的服務(wù)器數(shù)據(jù)。如果想要統(tǒng)計(jì)最新的領(lǐng)先與落后數(shù)字,需要在運(yùn)行此命令前抓取所有的遠(yuǎn)程倉庫。可以像這樣做:$ git fetch --all; git branch -vv
拉取
當(dāng) git fetch 命令從服務(wù)器上抓取本地沒有的數(shù)據(jù)時(shí),它并不會(huì)修改工作目錄中的內(nèi)容。它只會(huì)獲取數(shù)據(jù)然后讓你自己合并。然而,有一個(gè)命令叫作 git pull 在大多數(shù)情況下它的含義是一個(gè) git fetch 緊接著一個(gè) git merge 命令。如果有一個(gè)像之前章節(jié)中演示的設(shè)置好的跟蹤分支,不管它是顯式地設(shè)置還是通過 clone 或 checkout 命令為你創(chuàng)建的,git pull 都會(huì)查找當(dāng)前分支所跟蹤的服務(wù)器與分支,從服務(wù)器上抓取數(shù)據(jù)然后嘗試合并入那個(gè)遠(yuǎn)程分支。
由于 git pull 的魔法經(jīng)常令人困惑所以通常單獨(dú)顯式地使用 fetch 與 merge 命令會(huì)更好一些。
刪除遠(yuǎn)程分支
假設(shè)你已經(jīng)通過遠(yuǎn)程分支做完所有的工作了 - 也就是說你和你的協(xié)作者已經(jīng)完成了一個(gè)特性并且將其合并到了遠(yuǎn)程倉庫的 master 分支(或任何其他穩(wěn)定代碼分支)。可以運(yùn)行帶有 --delete 選項(xiàng)的 git push 命令來刪除一個(gè)遠(yuǎn)程分支。如果想要從服務(wù)器上刪除 serverfix 分支,運(yùn)行下面的命令:
$ git push origin --delete serverfix To https://github.com/schacon/simplegit- [deleted] serverfix基本上這個(gè)命令做的只是從服務(wù)器上移除這個(gè)指針。Git 服務(wù)器通常會(huì)保留數(shù)據(jù)一段時(shí)間直到垃圾回收運(yùn)行,所以如果不小心刪除掉了,通常是很容易恢復(fù)的。
總結(jié)
以上是生活随笔為你收集整理的5 Git 分支 - 远程分支的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 4 Git 分支 - 分支开发工作流
- 下一篇: 6 Git 分支 - 变基