远程仓库与 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 pushTo /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版)》,人民郵電出版社
總結
以上是生活随笔為你收集整理的远程仓库与 fetch 命令——Git 学习笔记 20的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: const与static的区别
- 下一篇: git checkout 对工作目录的影