【學了就忘】Git分支 — 45.分支合併(快進合併)

開發一個版本,採用的發佈流程:

  1. master分支的最新代碼拉取一個開發分支,在上面進行開發(這裏假設開發分支爲dev)。
  2. dev分支上不斷地進行提交版本,期間master分支也會有因爲其他版本上線,而不停有版本合併到master分支上。
  3. dev分支要測試發佈的時候,要把master分支的代碼,先合併到dev分支上。
  4. 最後發佈完成後,再把dev分支的代碼合併到master分支上。

1、分支合併說明

dev分支上的工作完成後,需要將其合併到主分支master上。合併過程其實很快,只需要將master指針指向dev指針指向的節點,然後再將HEAD指針指向master指針指向的節點即可。即分支的合併就是修改了兩個指針的指向而已。

對於合併的較形象的理解是:合併就是將原來在dev分支上的節點,全部投射到master分支上。

合併分支命令:git merge

對於分支的合併需要注意:如果需要將分支B合併到分支A上,首先要將當前分支切換到A分支上,然後再運行合併命令。

2、綜合示例

讓我們來看一個簡單的分支新建與分支合併的例子,實際工作中你可能會用到類似的工作流程。

例如:

  1. 開發某個網站。
  2. 爲實現某個新的用戶需求,創建一個分支。
  3. 在這個分支上開展工作。

正在此時,你突然接到一個電話說有個很嚴重的問題需要緊急修補。

你將按照如下方式來處理:

  1. 切換到主分支(production branch)或者開發分支上。
  2. 爲這個緊急任務新建一個分支,並在其中修復它。
  3. 在測試通過之後,切換回線上分支,然後合併這個修補分支,最後將改動推送到線上分支。
  4. 切換回你最初工作的分支上,繼續工作。

(1)正常工作情況說明

1)主分支情況

首先,你正在項目上工作,並且在 master 分支上已經有了一些提交。

如下:項目中已經有三次提交

L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git log --oneline
b97ccfd (HEAD -> master) 第3次提交,新增內容:branch test v3
f72a9fe 第2次提交,新增內容:branch test v2
fa2439a 第1次提交,新增readme.txt文件

圖解如下:

2)我的開發分支情況

爲實現某個新的用戶需求,創建一個分支,正在開發中,比如dev分支。

# 1.創建dev分支
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git checkout -b dev
Switched to a new branch 'dev'

# 2.進行開發工作
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (dev)
$ echo 'dev new file v1' > dev.txt

圖解如下:

因爲你已經切換到該分支進行開發了,也就是說,你的 HEAD 指針指向了 dev 分支。

(2)突然要處理新任務

現在你接到那個電話,有個緊急問題等待你來解決。

1)結束正在開發的任務,並提交到版本庫中

# 1.把dev分支中開發的文件提交到暫存區中
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (dev)
$ git add ./
warning: LF will be replaced by CRLF in dev.txt.
The file will have its original line endings in your working directory

# 2.然後提交到本地版本庫中
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (dev)
$ git commit -m '第4次提交,dev分支開發 dev.txt文件'
[dev 9eb3224] 第4次提交,dev分支開發 dev.txt文件
 1 file changed, 1 insertion(+)
 create mode 100644 dev.txt

# 3.查看歷史提交記錄
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (dev)
$ git log --oneline --graph
* 9eb3224 (HEAD -> dev) 第4次提交,dev分支開發 dev.txt文件
* b97ccfd (master) 第3次提交,新增內容:branch test v3
* f72a9fe 第2次提交,新增內容:branch test v2
* fa2439a 第1次提交,新增readme.txt文件

此時工作目錄中圖解如下:

注意:在你這麼做之前進行切換分支之前, 最好的方法是保持好一個乾淨的狀態工作目錄。

否則可能出現:

  • 切換分支失敗。
  • 或者分支污染。

2)切換到master分支上

# 1.查看dev分支工作目錄文件狀態,乾淨的。
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (dev)
$ git status
On branch dev
nothing to commit, working tree clean

# 2.切換到master分支上
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (dev)
$ git checkout master
Switched to branch 'master'

3)在master分支上創建修復分支

這個時候,你的工作目錄將恢復到你在開發dev分支之前的模樣,現在你可以專心修復緊急問題了。(那份代碼出現問題了,就從哪個代碼上開分支)

提示:當你切換分支的時候,Git 會重置你的工作目錄, Git 會自動添加、刪除、修改文件,以確保此時你的工作目錄和這個分支最後一次提交時的樣子一模一樣。

接下來,你要修復這個緊急問題。 我們來建立一個 hotfix 分支,在該分支上工作直到問題解決:

# 1.創建修復分支hotfix
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (dev)
$ git checkout -b hotfix
Switched to a new branch 'hotfix'

# 2.進行修復,增加V4版本
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (hotfix)
$ echo 'branch test v4' >> readme.txt

# 3.提交到本地版本庫
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (hotfix)
$ git commit -a -m '第5次提交,新增內容:branch test v4'
[hotfix 0690030] 第5次提交,新增內容:branch test v4
 Date: Sat Apr 17 18:29:35 2021 +0800
 1 file changed, 1 insertion(+)

# 4.查看本地庫克歷史提交信息
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (hotfix)
$ git log --oneline --graph --all
* 0690030 (HEAD -> hotfix) 第5次提交,新增內容:branch test v4
| * 9eb3224 (dev) 第4次提交,dev分支開發 dev.txt文件
|/
* b97ccfd (master) 第3次提交,新增內容:branch test v3
* f72a9fe 第2次提交,新增內容:branch test v2
* fa2439a 第1次提交,新增readme.txt文件

此時工作目錄中圖解如下:

接下來可以運行測試你的修復,確保修改是正確的後,將 hotfix 分支合併回 master 分支,並部署到線上。

4)將 hotfix 分支合併到 master 分支上

你可以使用 git merge 命令來達到上述目的:

# 1.查看工作目錄中文件狀態,非常乾淨
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (hotfix)
$ git status
On branch hotfix
nothing to commit, working tree clean

# 2.切換到master分支
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (hotfix)
$ git checkout master
Switched to branch 'master'

# 3.查看是否切換到主分支上
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git branch
  dev
  hotfix
* master

# 4.合併hotfix分支到master分支
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git merge hotfix
Updating b97ccfd..0690030
Fast-forward
 readme.txt | 1 +
 1 file changed, 1 insertion(+)

# 5.查看版本庫歷史提交記錄
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git log --oneline --graph --all
* 0690030 (HEAD -> master, hotfix) 第5次提交,新增內容:branch test v4
| * 9eb3224 (dev) 第4次提交,dev分支開發 dev.txt文件
|/
* b97ccfd 第3次提交,新增內容:branch test v3
* f72a9fe 第2次提交,新增內容:branch test v2
* fa2439a 第1次提交,新增readme.txt文件
# 發現HEAD -> master, hotfix,說明此時master, hotfix分支合併了。

此時工作目錄中圖解如下:

在合併的時候,你應該注意到了“快進(fast-forward)”這個詞。 由於你想要合併的分支 hotfix 所指向的提交 C5 是你所在的提交 C3 的直接後繼, 因此 Git 會直接將指針向前移動。

換句話說,當你試圖合併兩個分支時, 如果順着一個分支走下去能夠到達另一個分支,那麼 Git 在合併兩者的時候, 只會簡單的將指針向前推進(指針右移),因爲這種情況下的合併操作,沒有需要解決的分歧的地方,這就叫做 “快進(fast-forward)”合併。(快進合併是不會產生衝突的

現在,最新的修改已經在 master 分支所指向的提交快照中,你可以着手發佈該修復了。

5)合併完成後,刪除hotfix分支

關於這個緊急問題的解決方案發布之後,你需要準備回到被打斷之前時的工作中。 然而,你應該先刪除 hotfix分支,因爲你已經不再需要它了, master 分支已經指向了同一個位置。

所以你可以使用帶 -d 選項的 git branch 命令來刪除分支:

# 1.查看工作目錄中文件狀態,非常乾淨
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
nothing to commit, working tree clean

# 2.刪除hotfix分支
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git branch -d hotfix
Deleted branch hotfix (was 0690030).

# 3.查看版本庫中中的分支
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git branch
  dev
* master

6)之後我們就可以把修復的代碼推送到遠程倉庫了

這裏先不講解。

7)切換到dev分支,繼續自己的開發

現在你可以切換回你剛剛在工作的分支,繼續你的工作。

# 1.查看工作目錄中文件狀態,非常乾淨
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (dev)
$ git status
On branch dev
nothing to commit, working tree clean

# 2.切換到dev分支
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git checkout dev
Switched to branch 'dev'

# 巴拉巴拉繼續搬磚。

提示:你在 hotfix 分支上所做的工作並沒有包含到 dev 分支中。 如果你需要拉取 hotfix 所做的修改,你可以使用 git merge master 命令將 master 分支合併入 dev 分支,或者你也可以等到 dev 分支完成其使命,再將其合併回 master 分支。

3、補充:分支選項

--merged--no-merged 這兩個有用的選項,可以過濾這個列表中,已經合併或尚未合併到當前分支的其他分支。

(1)--merged 選項

如果要查看哪些分支已經合併到當前分支,可以運行 git branch --merged命令:

$ git branch --merged
  iss53
* master

因爲之前已經合併了 iss53 分支,所以看到它在列表中。

在列表中,分支名字前沒有 * 號的分支,通常可以使用 git branch -d 刪除掉;你已經將它們的工作整合到了另一個分支,所以並不會失去任何東西。

(2)--no-merged 選項

查看所有未合併到當前分支的其他分支,可以運行 git branch --no-merged命令:

$ git branch --no-merged
  testing

這裏顯示了testing分支。 因爲它包含了還未合併的工作(也就是該分支開發完還沒有合併),嘗試使用 git branch -d 命令刪除它時會失敗:

$ git branch -d testing
error: The branch 'testing' is not fully merged.
If you are sure you want to delete it, run 'git branch -D testing'.

如果真的想要刪除該分支,並丟掉那些工作,可以使用 -D 選項強制刪除它。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章