遠端倉庫與 fetch 命令——Git 學習筆記 20
遠端倉庫是指託管在因特網或其他網路(比如區域網)中的版本庫。 你可以有好幾個遠端倉庫,通常有些倉庫對你只讀,有些則對你可讀可寫。 與他人協作涉及管理遠端倉庫以及根據需要推送或拉取資料。
檢視遠端倉庫
如果想檢視你已經配置的遠端倉庫伺服器,可以執行 git remote
命令。它會列出你指定的每一個遠端伺服器的簡寫。 如果你已經克隆了倉庫,那麼至少應該能看到 origin
-—— 這是 Git 給你起的克隆的倉庫伺服器的預設名字:
$ git remote
origin
你也可以指定選項 -v
,會顯示遠端倉庫對應的簡寫和它的 URL。
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
上面的命令表示,當前只有一臺遠端主機,叫做 origin,它的網址是https://github.com/schacon/ticgit
fetch 和 push 對應的都是這個網址,當然,也可以對應不同的網址。
如果你的遠端倉庫不止一個,該命令會將它們全部列出。 例如:
$ git remote -v
bakkdoor https://github.com/bakkdoor/grit (fetch)
bakkdoor https://github.com/bakkdoor/grit (push)
cho45 https://github.com/cho45/grit (fetch)
cho45 https://github.com/cho45/grit (push)
defunkt https://github.com/defunkt/grit (fetch)
defunkt https://github.com/defunkt/grit (push)
koke git://github.com/koke/grit.git (fetch)
koke git://github.com/koke/grit.git (push)
origin git@github.com:mojombo/grit.git (fetch)
origin git@github.com:mojombo/grit.git (push)
可以看到,一共有5個遠端倉庫。注意到這些遠端倉庫使用了不同的協議(從地址的格式就可以看出來)。
新增遠端倉庫
執行 git remote add <shortname> <url>
新增一個新的遠端倉庫,同時指定一個簡寫:
$ git remote
origin
$
$ git remote add pb https://github.com/paulboone/ticgit
$
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb https://github.com/paulboone/ticgit (fetch)
pb https://github.com/paulboone/ticgit (push)
現在你可以在命令列中使用字串 pb 來代替整個 URL (即https://github.com/paulboone/ticgit
)。
git fetch
命令
要從遠端倉庫中獲得資料,可以執行:
$ git fetch [remote-name]
這個命令會訪問遠端倉庫,從中取回所有你還沒有的資料。 執行完成後,你將會擁有那個遠端倉庫中所有分支的引用,可以隨時合併或檢視。
如果你使用 clone 命令克隆了一個倉庫,那麼 Git 會自動將其新增為遠端倉庫並預設以 “origin” 為簡寫。 所以,git fetch origin
會抓取克隆(或上一次抓取)後新推送的所有工作。
必須注意 :git fetch
命令僅僅是將資料拉取到你的本地倉庫,它並不會自動合併或修改你當前的工作。當準備好時你必須手動合併。
如果你覺得上面的文字讓你雲裡霧裡,那麼請看下文。
假設伺服器上有一個版本庫:
最近的 2 次提交標記為 A 和 B。
這時候,你把這個版本庫克隆到了本地:
克隆之後:
- 原始版本庫中的所有提交都複製到克隆版本庫。
- 克隆版本庫中有一個名為
origin/master
的遠端追蹤分支( remote-tracking branch),它指向原始版本庫中 master 指向的提交,也就是 B。 - 克隆版本庫中建立了一個新的本地追蹤分支( local-tracking development branches),稱為 master 分支。這個 master 分支指向
origin/master
指向的提交,也就是 B。
克隆後,Git 會選擇新的 master 分支作為當前分支,並自動檢出它。因此,除非切換分支,否則克隆後所做的任何修改都會影響 master 分支。
在圖中,原始版本庫和派生的克隆版本庫中的開發分支都由深灰色作為背景色,而遠端追蹤分支則用淺灰色作為背景色。在 Git 的實現中,深灰色背景的分支屬於 refs/heads/
名稱空間,淺灰色背景的分支的屬於refs/remotes/
名稱空間。
請注意,本地追蹤分支和遠端追蹤分支都是私有的,並只存在於各自的版本庫中。
遠端追蹤分支是遠端分支狀態的引用。它們是你不能移動的本地引用,當你做任何網路通訊操作時,它們會自動移動。遠端追蹤分支像是你上次連線到遠端倉庫時,那些分支所處狀態的書籤。例如,如果你想要看你最後一次與遠端倉庫
origin
通訊時master
分支的狀態,你可以檢視origin/master
分支。
在本地 master
分支工作的時候,本地的 master
會向前移動,而**origin/master
是不可以移動的**。正如下圖所示,你的開發使 master
分支變長了:在提交 B 的基礎上多出 2 個新的提交 —— X 和 Y。
在你開發期間,如果原始版本庫沒有任何變化,那麼你可以很容易地把 X 和 Y 推送到上游:Git 會把你的提交傳輸到原始版本庫,並把它們新增到 B 的後邊,然後 Git 會把你的提交合併到原始版本庫的 master 分支,實際上這是一種特殊的合併操作 —— 快進(fast-forward),快進本質上是一個簡單的線性歷史記錄推進操作。
如下圖所示:
正如前文所述,在推送(push)的過程中,本地倉庫與遠端倉庫 origin
進行了“通訊”, origin/master
分支會和遠端倉庫的 master
保持同步,所以,你的origin/master
分支也指向了 Y。
以上的舉例是理想情況。實際情況是,在你開發期間,任何其他有權訪問原始版本庫的開發人員可能已經做了進一步開發,並把她的修改推送到該版本庫。如下圖:
在這種情況下,我們說版本庫的歷史記錄在提交 B 處分叉(diverged 或 forked)了。當你嘗試推送,Git 會拒絕它並用一條如下所示的訊息告訴你有關的衝突。
$ git push
To /tmp/Depot/public_html
! [rejected] master -> master (non-fast forward)
error: failed to push some refs to '/tmp/Depot/public_html'
那麼,什麼是你真正想要做的?你想覆蓋其他人員的工作,還是想要合併兩組歷史記錄?
提示
如果你想覆蓋所有其他變化,也是可以的。只要在你的
git push
中使用-f
選項即可。不過我建議你不要這麼做,否則你的夥伴會恨你的……
更多的時候,你不想覆蓋別人的提交,你只是想新增你自己的修改。在這種情況下,你必須在推送之前在你的版本庫中合併兩組歷史記錄。這時候,就該 fetch
大顯身手了。
要讓 Git 合併兩組歷史記錄,那麼這兩組歷史記錄必須存在於同一個版本庫。現在你的 X 和 Y 提交本身就在你的版本庫裡,為了把 origin
中的 C 和 D 提交納入你的版本庫,你可以用 git fetch
命令進行抓取。這個命令會訪問遠端倉庫,從中拉取所有你還沒有的資料,如下圖:
注意,引入 C 和 D 這組歷史記錄並不能改變由 X 和 Y 代表的歷史記錄,所以你不用擔心 fetch 操作會破壞你的勞動成果。fetch 後,這兩組歷史記錄同時存在於你的版本庫中,形成一幅比較複雜的圖,簡單來說就是在 B 處分叉了。你的歷史記錄由 master 分支代表,遠端歷史記錄則由 origin/master 遠端追蹤分支代表。
講到這裡,fetch 命令就講完了,剩下的工作(merge, push)以後再說。
參考資料
【1】《Git 分支:遠端分支》https://git-scm.com/book/zh/v2/
【2】《Git 版本控制管理(第2版)》,人民郵電出版社
【3】《精通 Git(第2版)》,人民郵電出版社
相關文章
- 取得 Git 倉庫 —— Git 學習筆記 04Git筆記
- git 遠端倉庫Git
- git倉庫修改遠端倉庫Git
- 從零開始學習Git--遠端倉庫Git
- fetch 與引用規格(refspec)—— Git 學習筆記 23Git筆記
- Git 使用遠端倉庫Git
- git-遠端倉庫Git
- git push到遠端倉庫Git
- 記錄每次更新到倉庫 —— Git 學習筆記 10Git筆記
- git 修改本地倉庫的遠端倉庫地址Git
- 圖解遠端版本庫開發週期 —— Git 學習筆記 22圖解Git筆記
- IDEA更改遠端git倉庫地址IdeaGit
- 如何修改 Git 遠端倉庫 URLGit
- git 本地push到遠端倉庫Git
- 本地倉庫推送到遠端倉庫的git操作Git
- git常用命令及手動關聯git本地和遠端倉庫Git
- git 入門教程之遠端倉庫Git
- git克隆遠端倉庫的指定分支Git
- git連線遠端倉庫的方式Git
- 修改git遠端倉庫分支名稱Git
- Git remote 遠端倉庫連結管理GitREM
- docker學習筆記(2)- 倉庫Docker筆記
- 【Git】fork遠端倉庫,fork倉庫同步和提交pull requestGit
- git checkout 命令詳解—— Git 學習筆記 16Git筆記
- git status 命令總結 —— Git 學習筆記 06Git筆記
- 與遠端倉庫保持同步
- 教你玩轉Git-提取遠端倉庫Git
- git 從遠端倉庫獲取所有分支Git
- Git使用小技巧之多個遠端倉庫Git
- Git 系列教程(8)- 遠端倉庫的使用Git
- git的跟蹤分支和遠端跟蹤分支學習筆記Git筆記
- Ubuntu Terminal命令列新建倉庫並推送到遠端倉庫Ubuntu命令列
- git reset 命令詳解(一)—— Git 學習筆記 07Git筆記
- git reset 命令詳解(二)—— Git 學習筆記 08Git筆記
- git換倉庫命令Git
- 教你玩轉Git-刪除遠端倉庫Git
- 【第十篇】- Git 遠端倉庫(Github)Github
- 【git】強制覆蓋原生程式碼(與git遠端倉庫保持一致)Git