Git輕松入門2:分支篇


什么是分支

在玩劇情類游戲時,不同的選擇會觸發不同的劇情路線,每條劇情路線都會獨立發展,最終走向不同的結局。

Git中所謂的“分支(branch)”就如同游戲中的劇情路線,用戶可以為項目建立不同的分支,使得項目能在不同的分支里獨立進行,並且互不干預。

當用戶初始化一個倉庫時,Git會自動為其建立一條主分支,默認稱其為master。若用戶沒有創建其他分支,那么項目發展的各個版本就默認存儲在這條 master 分支上。

分支指令介紹

分支的新建和切換

假設你正在項目上工作,並且在 master 分支上已經有了如下的提交。

對應的圖即為如下:

master 指針指向該分支上最新的提交; HEAD 指針指向的是當前所在分支。

此時你發現了項目中有一個代號為#11的bug需要你解決。你決定專門新建一個分支,在那條分支上把該問題解決。於是你敲入了新建分支的指令。

上面兩行命令可以僅用一條命令替代:$ git branch -b bug#11

當我們在創建新的分支時,實際上是創建一個新的指針。它會指向 master 此時指向的提交。當我們切換到分支 bug#11時,HEAD 指針就會指向 bug#11,如下圖所示。

此外,我們可以用如下命令查看了目前倉庫中存在的分支。

可以看到目前共存在2個分支,其中帶*號的是目前所在分支:master

分支的作用

於是你開始在 bug#11 這條分支上工作,並作出了如下的提交(commit)。

於是 bug#11 指針往前移動了一步,而 master 指針還是留在原地。

這時,當你用 $ git checkout master 命令切換回 master 分支時,你發現剛才在 bug#11 分支上新建的 log.txt 文件不見了,當前的工作目錄和你開始在 bug#11 分支工作前一模一樣。

這就是分支的好處,它將工作切分開來,讓工作多線獨立發展。

合並分支

我們將介紹在合並分支時會遇到的3種情況。

Fast-Forward

此時,你已經把 #bug11 修復完畢,你決定把這項修復合並到主線 master 中。於是,你使用了 $ git merge 命令來實現這個目的。

在合並的時候,你注意到了“快進(Fast-forward)”這個詞。當你試圖合並兩個分支時, 如果順着一個分支走下去能夠到達另一個分支,那么 Git 在合並兩者的時候, 只會簡單的將指針向前推進,因為這種情況下的合並操作沒有需要解決的分歧——這就叫做 “快進(fast-forward)”,如圖所示。

此時合並完成,所以你也不再需要 bug#11 分支了。你可以使用帶 -d 選項的 $ git branch 命令來刪除分支:

'recursive' strategy

此時,你又發現了項目中有一個代號為 bug#31 的漏洞需要修復,於是你先用 $ git branch bug#31 命令新建了一個分支。

現在的你還在 master 這條分支上工作:你將 Scheduling.txt 的文件內容修改為 Project Scheduling - 85% Done., 然后commit這次的修改。

此時,對應的圖為如下:

現在的你感到心滿意足,決心切換到 bug#31 分支上開始修復 bug#31。於是你先用 $ git checkout bug#31 命令切換到了該分支。

接着你辛辛苦苦了一整天,總算把 bug#31 修復完了。於是你修改了 log.txt 文件里的內容,加上了一行Fixed bug#31. ,並commit這次的修改,此時的圖對應如下:

現在,你決定把對 bug#31 的修復應用到 master 分支中來,於是你切換回 master 分支,然后再次調用了 $ git merge 命令:

你發現這次提示的和之前在合並 bug#11 分支時提示的不太一樣。因為此時,你想合並的 bug#31 指向的最新提交 C4 並不是 master 指向的最新提交 C3 的直接后繼(換句話說,C3 不能順着一條路走到 C4)。所以Git沒法再那么通過簡單的移動指針來完成合並了。

Git會找到 C3C4 的共同祖先 C2,然后做一個三方合並。

那么什么是三方合並呢?

例子1:A是B和C的共同祖先。B相對A的改動是刪掉了3,C相對A的改動是增加了1。那么B和C合並的結果就是123。

例子2:A是B和C的共同祖先。B相對A的改動是刪掉了1,C相對A的改動是增加了3。那么B和C合並的結果就是23。

所以簡單來說,三方合並就是把B方和C方相對於共同祖先A方的改動分別應用到合並結果上。

剛才,C3 相對於 C2 的改動是修改了 Scheduling.txt 文件的內容,而 C4 相對於 C2 的改動是修改了 log.txt 文件里的內容,將這兩項改動都應用到合並結果中,就得到了一個既修改了 Scheduling.txt 又修改了 log.txtC5

遇到沖突時的合並

有時候合並操作不會如此順利。 如果你在兩個不同的分支中,對同一個文件進行了不同的修改,Git 就沒法干凈的合並它們。

例如:你在 bug#31 分支中在 README.md 文件中添加了一行 I like Git.;在 master 分支中對 README.md 文件添加了一行 Git is good.,然后再執行 $ git merge 命令:

在兩個分支中,你都對 README.md 文件進行了修改,因此就會產生合並沖突。

打開 README.md 文件會看到如下內容,其中 <<<<<<< HEAD======= 之間的內容是 HEAD 指向分支里的內容,即 master=======>>>>>>> bug#31 之間的是 bug#31 分支里的內容。

你手動修改了這個文件,修改后的內容如下。

Git輕松入門1:本地倉庫篇,我們提到過,文件修改后,需要執行 $ git add$ git commit 兩個步驟。所以現在,你同樣需要執行這兩個步驟,而當你敲完命令,你會發現提示合並成功。

總結

總結一下今天出現過的幾個Git命令:

# 列出該倉庫存在的分支,當前分支的前面會帶有*號
$ git branch

# 創建分支
$ git branch [branch-name] 

# 切換分支
$ git checkout [branch-name]

# 創建分支並立刻切換到該分支下
$ git checkout -b [branch-name]

# 刪除分支
$ git branch -d [branch-name]

# 合並分支
$ git merge [branch-name]

分支的作用在於將工作切分開來,使得工作可以多線獨立發展。以上是本講關於分支命令的概括。此外,本講還介紹了Git采取的3種合並策略:Fast-forward(直接移動指針),recursive strategy(采取三方合並)以及merge conflict(手動修改存在沖突的文件)。

參考

  1. http://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging
  2. https://www.zhihu.com/question/30200228
  3. https://www.liaoxuefeng.com/wiki/896043488029600/900003767775424
  4. https://www.runoob.com/git/git-branch.html

 
有問題歡迎大家在評論區留言,轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM