圖解遠端版本庫開發週期 —— Git 學習筆記 22

ARM的程式設計師敲著詩歌的夢發表於2018-11-25

圖解遠端版本庫開發週期

克隆版本庫

假設伺服器上有一個簡單的版本庫:

在這裡插入圖片描述
最近的 2 次提交用 A 和 B 表示。

這時候,你把這個版本庫克隆到了本地:

在這裡插入圖片描述

克隆之後,我們看看這個克隆到本地的版本庫都有些什麼:

  • 原始版本庫中的所有提交都複製到克隆版本庫。
  • 克隆版本庫中有一個名為 origin/master遠端追蹤分支( remote-tracking branch)
  • 在克隆版本庫中, origin/master分支指向原始版本庫中 master 指向的提交,也就是 B。
  • 克隆版本庫中建立了一個新的本地追蹤分支( local-tracking branch),稱為 master 分支。這個 master 分支指向 origin/master指向的提交,也就是 B。

克隆後,Git 會選擇新的 master 分支作為當前分支,並自動檢出它。因此,除非切換分支,否則克隆後所做的任何修改都會影響 master 分支。

在圖中,原始版本庫和派生的克隆版本庫中的開發分支都由深灰色作為背景色,而遠端追蹤分支則用淺灰色作為背景色。在 Git 的實現中,深灰色背景的分支屬於 refs/heads/ 名稱空間,淺灰色背景的分支屬於 refs/remotes/名稱空間。

請注意,本地追蹤分支和遠端追蹤分支都是私有的,並只存在於各自的版本庫中。

快進推送

在本地的 master分支工作的時候,本地的 master 會向前移動,而 origin/master 是不可以移動的。正如下圖所示,你的開發使 master 分支變長了:在提交 B 的基礎上多出 2 個新的提交 —— X 和 Y。

在這裡插入圖片描述

在你開發期間,如果原始版本庫沒有任何變化,那麼你可以很容易地把 X 和 Y 推送到上游:Git 會把你的提交傳輸到版本庫,並把它們新增到 B 的後邊,然後 Git 會對 master 分支執行一種特殊的合併操作 —— 快進(fast-forward),快進本質上是一個簡單的線性歷史記錄推進操作。如下圖所示:

在這裡插入圖片描述

非快進推送

但是,在你開發期間,任何其他有權訪問原始版本庫的開發人員可能已經做了進一步開發,並把他的修改推送到該版本庫。如下圖:

在這裡插入圖片描述

在這種情況下,我們說版本庫的歷史記錄在提交 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 命令

更多的時候,你不想覆蓋別人的提交,只是想新增你自己的修改。在這種情況下,你必須在推送之前在你的版本庫中合併兩組歷史記錄。這時候,就該 fetch 命令大顯身手了。

要讓 Git 合併兩組歷史記錄,那麼這兩組歷史記錄必須存在於同一個版本庫的兩個不同分支上。現在你的提交 X 和 Y 本身就在你的版本庫裡,為了把 Origin 中的提交 C 和 D 納入你的版本庫,你可以用 git fetch命令進行抓取。這個命令會訪問遠端倉庫,從中拉取所有你還沒有的資料。

在這裡插入圖片描述

注意,引入 C 和 D 這組歷史記錄並不能改變由 X 和 Y 代表的歷史記錄。所以,你沒有必要擔心 fetch 之後會覆蓋你的工作成果。fetch 之後,這兩組歷史記錄同時存在於你的版本庫中,形成一幅比較複雜的圖,簡單來說就是在 B 處分叉了。你的歷史記錄由 master 分支代表,遠端歷史記錄則由 origin/master 遠端追蹤分支代表。

merge 命令

既然這兩組歷史記錄已經存在於一個版本庫中了,那就整合它們吧。

提示

你不能把 master 分支合併到 origin/master 分支,因為 origin/master 是遠端引用,遠端引用是隻讀的。 雖然可以 git checkout 到某個遠端引用,但是 Git 並不會將 HEAD 引用指向該遠端引用。因此,你永遠不能通過 commit 命令來更新遠端引用。Git 將這些遠端引用作為記錄遠端伺服器上各分支最後已知位置狀態的書籤來管理。

所以,我們要做的就是把 origin/master 分支合併到 master 分支。

git merge origin/master

在這裡插入圖片描述

假設合併過程很順利,沒有任何衝突,現在,你的版本庫已經包含了 origin 版本庫和你的版本庫中的最新變更。但是反過來是不成立的:origin 版本庫裡依然沒有你的變更。

push 命令

為了讓其他人員共享你的變更,你可以用 git push 命令把合併後的歷史記錄從你的master 分支上推送回 origin 版本庫。推送後如下圖所示:

在這裡插入圖片描述

最後,你可以看到 origin 版本庫已經更新了你的開發,你的版本庫和 origin 版本庫已經完全更新並再次同步了。

【End】

參考資料

《Git 版本控制管理(第2版)(人民郵電出版社)》

相關文章