將 Git 分支合併到 Master 的最佳方法
git 最強大的功能之一是分支建立和合並操作。Git 允許使用者建立一個新分支並將它們合併到開發程式碼中。此功能通過鼓勵更具體、更小和更精細的任務來改進多個專案的開發流程工作流。
在本教程文章中,我們將討論將 git 功能分支合併到 master 的不同方法。
git 的主要優點是它的分支系統。GIT 的所有魔力都在這些分支上!主分支將進行所有修改。因此,目標不是直接在這個分支上進行修改,而是在其他分支上進行修改,經過各種測試後,將它們整合到主分支上。
在我們的教程中,為簡單起見,我們假設有兩個分支,master
分支和稱為 feature-1
的特性分支。主分支是包含生產程式碼的主分支,第二個分支是執行修改或實現新功能的地方。最後,如果一個功能或錯誤被批准,它將被合併到 master
。
下面開始用一個真實的例子來演示兩個分支的合併。首先,我們需要以下內容。
先決條件
在 GitHub 上建立倉庫
可以按照 Github 中的介紹建立初始倉庫
接下來,使用倉庫頁面上的新增檔案
按鈕在 Master 分支上新增兩個檔案。檔名如下。
file1.txt
file2.txt
在本例中,以下文字內容分別新增到 file1.txt
和 file 2.txt
。
$ cat file1.txt
This is dummy text line 1
This is dummy text line 2
$ cat file2.txt
This is dummy test in 2nd file
克隆倉庫
接下來,將你新建立的倉庫從 GitHub 克隆到你的系統以建立程式碼的本地副本。克隆 URL 可以從程式碼
按鈕中檢索,如下所示。
使用以下命令進行克隆。
$ git clone git@github.com:project/demorepo.git
克隆成功後,使用以下命令顯示並驗證 master 分支檔案的內容:
$ cat file1.txt
This is dummy text line 1
This is dummy text line 2
$ cat file2.txt
This is dummy test in 2nd file
建立特徵分支
$ git branch feature-1
此命令會建立一個新分支,並且不會在 git 上建立新的提交。
檢出功能分支
之前,我們使用 git branch feature-1
建立了一個新分支。但是,活動分支是 master
分支。要啟用新分支,請在終端中使用以下命令:
$ git checkout feature-1
Switched to branch 'feature-1'
上面的命令會將活動分支從 master
切換到 feature-1
。現在,這個分支已經可以進行單獨開發了。
修改功能分支中的檔案
我們將在 feature-1
分支中新增一些提交或新增新行。在這種情況下,file2.txt
將在本地修改,然後合併回主分支。
對於到目前為止的更改,我們的提交圖如下所示。A 和 E 都代表 master
和 feature-1
分支狀態。目前,提交 A
和 E
相同,因為在切換期間沒有更改任何檔案。
A ← master
\
E ← feature-1
現在,file1.txt
更新為新文字。使用此命令更新內容。
$ echo "file update in feature branch" > file1.txt
現在,file2.txt
具有以下內容。
$ cat file2.txt
This is dummy test in 2nd file
file1.txt
中新舊內容之間的差異可以使用以下命令進行驗證。
$ git diff
diff --git a/file1.txt b/file1.txt
index 11d66d4..48c9378 100644
--- a/file1.txt
+++ b/file1.txt
@@ -1,2 +1 @@
-This is dummy text line 1
-This is dummy text line 2
+file update in feature branch
現在,暫存此檔案並通過以下命令建立本地提交。
$ git add file1.txt
$ git commit -am "update file via feature-1"
[feature-1 22b60b8] update file via feature-1
1 file changed, 1 insertion(+), 2 d
提交樹的當前快照如下所示。這裡 F
是在上一步中建立的新提交。
A ← master
\
E --- F ← feature-1
為了演示一個真實的例子,遠端 master
也被其他開發人員同時更改,這些更改作為提交 C
和提交 D
推送到 master。
A --- B --- C --- D ← master
\
E --- F ← feature-1
以下是 master 分支的 Github 倉庫中 file1.txt
的更新內容。請注意,第 2 行已更新,第 3 行和第 4 行是新建立的。
這也可以通過使用以下命令在命令 shell 中實時視覺化你的分支歷史記錄來本地驗證。
$ git fetch
$ git log --all --decorate --oneline --graph
在 Git 中準備合併
使用 Git,我們有兩種可能性將我們的功能分支更改與遠端 master
分支合併:
-
merge
方法
Gitmerge
是一個將更改提交到另一個分支的命令。它允許開發人員從功能分支中獲取他們獨立的程式碼行,並通過 git 合併工具將它們整合到 master 上的單個分支中。 -
rebase
方法
Gitrebase
是另一個用於基本相同目的的命令,只是它的執行方式非常不同。
讓我們詳細瞭解這兩種方式:
使用 Git 中的 merge
方法將分支合併到 Master 中
merge
旨在將 feature
和 master
分支合併到保留所有相關分支內容的提交中。Git 實現了這一點,即所謂的合併提交
。這也意味著 merge
操作多個分支。
當分支分叉時,即一個不是另一個的祖先。Git 可以通過進行具有多個父項的新附加提交來實現合併。在下圖中,如果你在不同的分支中有提交 D
和提交 F
並混合分支(通過 git merge
),結果是提交 G
,其父項是 B
和 E
。
A --- B --- C --- D ---
\ \
\ G ← master
E --- F --------- /
在上圖中,G
是一個新建立的提交,完全由 git 建立。這個提交有兩個父節點!他們有一個命令:
- 第一個父節點是
D
,之前是master
。 - 第二個父節點是
F
,之前是feature-1
。
這種型別的提交稱為合併提交。
現在切換回我們的倉庫示例並將新建立的 feature-1
分支合併到 master
首先,檢查主分支。
$ git checkout master
現在,將遠端 master
更改拉到本地的 master
。
$ git pull origin master
From github.com:repo/demorepo
* branch master -> FETCH_HEAD
Updating 17cc6b4..a802b6b
Fast-forward
file1.txt | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
之後,使用以下命令將功能分支,即 feature-1
合併到當前活動的分支。
$ git merge feature-1
如果此步驟成功完成,feature-1
分支將與 master
分支完全合併。但是,如果 git 不能自動解決這些合併衝突,它將失敗並顯示合併衝突錯誤。
這是一個非常典型的場景;當兩個分支修改檔案的同一部分並且 git 無法解析要使用的部分時,就會發生這種情況。這正是我們示例中發生的情況。下面通過 git 顯示了這種情況。
Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
Automatic merge failed; fix conflicts and then commit the result.
每當 git 遇到衝突時,它都會新增 <<<<<<<
& ========
以突出顯示導致衝突的部分,這需要手動解決。
一旦決定將哪個部分保留在檔案的最終主版本中,個人必須刪除不相關的程式碼(包括衝突指示符)。最後,將更改推送到遠端分支,如下所示。
$ git add .
$ git commit -am "resolving the mergeconflict"
[master 1acce69] resolving the mergeconflict
$ git push
這樣 feature-1
分支成功合併到遠端 master
。
接下來,我們將使用以下命令再次驗證分支歷史記錄。
git log --all --decorate --oneline --graph
我們可以驗證 git merge
是否建立了一個 Merge Commit
,commit-id 為 1acce69
以將 feature-1
分支與 origin/master
合併。
使用 rebase
方法將分支合併到 Master
再次考慮我們的 feature 和 master 分支不同步需要合併的情況。讓我們還回顧一下之前顯示這種情況的圖示。
A --- B --- C --- D ← master
\
E --- F ← feature-1
作為合併的替代方法,你可以使用 rebase 選項將分支 feature-1
合併到分支 master
。rebase
通過簡單地將來自 feature 分支的提交放在 master 分支的前面來統一所涉及的分支。
這將通過以下命令實現,
git checkout master
git pull
git checkout feature-1
git rebase master
執行 rebase 後,我們可以得到如下圖所示。
A --- B --- C --- D----(operation rebase)----- E--------F ← master
從上圖可以看出,rebase
所做的一些好事是產生線性、更清晰、更易於閱讀的提交歷史。通過合併,它也不會產生額外的奇怪的 merge commit
。
這種方法的缺點是 rebase 改變了所涉及分支的整個結構,包括重寫這些分支的提交歷史。由於 rebase
不會建立 merge commit
,你無法獲得兩個分支何時合併的可追溯性,因為 rebase 在流程結束時生成一個線性分支。
まとめ
這兩個命令都非常有用;但是,在不同的情況下,雙方各有優勢。
Git rebase
- 簡化複雜的歷史。
- 避免在具有繁忙分支的倉庫中合併提交噪音。
- 如果使用不當,則有風險,因為它不會儲存歷史。
Git merge
- 使用簡單。
- 由於每次都會建立一個額外的合併提交,它會導致提交歷史看起來混亂和骯髒。
- 保留完整的歷史和時間順序。