Git merge 與 rebase 初學者指南
更新日期: 2024 年 12 月 9 日
本文為 Git 指令基本介紹教學,第 3 篇:
- Git 新手入門指南
- Git 分支與版本控制入門指南
- Git merge 與 rebase 初學者指南 👈 所在位置
- Git Reset:退回版本與分支拆分指南
- 解決 Git 衝突 (Conflict) 的完整指南
Git 的 merge 與 Rebase 是版本控制中處理分支的核心操作。
這兩種方式各有優勢,使用得當可以幫助我們維持乾淨且有序的開發歷史。
本文將針對這兩種功能進行詳細說明,並介紹如何在日常開發中正確運用。
合併分支 (Fast-Forward)
如果兩個分支沒有衝突,且一個分支的進度完全包含在另一個分支內,Git 將直接將 HEAD
向前移動,這稱為快進合併。
合併的基本概念
當我們在不同的分支上進行開發,最終需要將變更整合到主分支時,可以使用 git merge
。
這個操作會將兩個分支的歷史與變更內容合併。
指令範例
假設我們有兩個分支:
- 最新分支:
master
- 舊分支:
cat
合併方式取決於當前 HEAD
的指向。
例如:
git merge cat
若 HEAD
指向 master
,但目標分支(如 cat
)沒有更新內容,會出現提示:
Already up to date.
正確的合併步驟
- 切換到目標分支(如
cat
):git switch cat
- 合併來源分支(如
master
):git merge master
這樣可以確保 cat
分支正確地包含 master
的更新內容。
範例輸出:
Updating c60fbcd..1908ada
Fast-forward
d.html | 0
e.html | 0
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 d.html
create mode 100644 e.html
合併中的問題處理
忘記切換分支怎麼辦?
如果你不小心在 master
上直接進行操作,導致新分支沒有更新,可以使用以下方法:
- 為錯誤提交的變更重新命名分支:
git branch 新分支名稱
- 重新切換到正確的分支進行操作。
關鍵點: 分支只是標籤 (label),Git 的核心是提交的線性結構,操作錯誤時可透過標籤重新整理工作流。
無法快進的合併(非 Fast-Forward 合併)
當兩個分支各自有獨立的提交歷史時,無法使用快進合併 (Fast-Forward)。
這種情況下,Git 會創建一個新的合併提交 (merge commit),將兩個分支的內容整合到一起。
合併的情境說明
假設我們有兩個分支:
master
分支已經有兩個提交。feature
分支也在master
的基礎上新增了兩個提交。
這樣的結構可能如下:
[提交 A] <- [提交 B] <- HEAD, master
\
[提交 C] <- [提交 D] <- HEAD, feature
此時,由於 master
和 feature
各自有新的提交,無法通過快進合併(Fast-Forward)。因此,Git 會創建一個新的合併提交節點。
合併的步驟
- 切換到其中一個分支
假設我們希望將feature
合併到master
,首先切換到master
分支:
git switch master
- 執行合併指令
使用git merge
合併feature
分支:
git merge feature
- 合併提交
Git 會分析兩個分支的變更,並創建一個新的合併提交節點,將兩者的內容整合在一起:
[提交 A] <- [提交 B] <- [合併提交] <- HEAD, master
\ /
[提交 C] <- [提交 D] <- feature
範例輸出
執行合併時,若沒有衝突,終端機會顯示類似以下輸出:
Merge made by the 'ort' strategy.
c.html | 1 +
d.html | 1 +
2 files changed, 2 insertions(+)
- 表示合併過程中,Git 自動處理了兩個分支的變更,新增了必要的內容。
合併的注意事項
- 解決衝突
如果兩個分支中有相同檔案的衝突,Git 會要求手動解決衝突,並在解決後提交:git add <解決後的檔案> git commit
- 合併提交的意義
合併提交節點保存了完整的分支歷史,方便追蹤分支變更的來源。
Rebase:重寫歷史與整理分支
Rebase 是將一個分支的提交重新基於另一個分支上,達到整合的目的。
不同於合併,Rebase 不會保留分支的歷史結構,而是產生一條線性平整的提交記錄。
指令範例
假設有以下兩個分支:
a
分支:有數個提交節點b
分支:基底節點
透過 Rebase,可以將 a
分支的提交基於 b
分支:
- 切換到目標分支:
git switch a
- 將
a
分支重新基於b
:
git rebase b
Rebase 的工作原理
- 先將
HEAD
指向基底分支(如b
)。 - 將基底分支的節點整合到當前分支(如
a
)。 - 複製當前分支的節點並將其添加到基底分支之後。
注意: Rebase 不會刪除舊的提交節點,只是暫時隱藏它們。如果需要,可以使用分支重新貼標籤取回這些提交。
Merge vs Rebase 的比較
功能 | Merge | Rebase |
---|---|---|
歷史紀錄 | 保留所有的提交紀錄,可能造成分支混亂 | 產生線性紀錄,歷史乾淨 |
使用情境 | 合併開發分支到主分支時,保持歷史完整 | 整理分支提交,避免多餘的合併節點 |
結果 | 提交歷史不平整,但更完整 | 提交歷史線性化,易於閱讀 |
什麼時候用 Rebase?
在需要乾淨歷史(如代碼審查、提交展示)時,推薦使用 Rebase。日常開發中,若不需要過於關注歷史紀錄,可以使用 Merge。
總結
Git 的合併與 Rebase 是處理分支與提交的兩種強大工具。Merge 保留完整的歷史結構,適合團隊協作;Rebase 則更適合個人開發時整理提交,保持歷史紀錄的簡潔。
了解兩者的運作原理與使用情境,可以幫助你更高效地管理分支並維持乾淨的代碼庫!