Stories

Detail Return Return

Git合併選Rebase還是Merge?弄懂這3點,從此不再糾結 - Stories Detail

大家好!今天我們來聊聊 Git 中兩個非常重要但又容易混淆的概念:git rebasegit merge

在日常團隊協作開發中,我們經常需要將不同分支的代碼進行合併。Git 提供了兩種主要的合併方式:git mergegit rebase。雖然它們都能實現分支合併的目的,但使用方式和最終效果卻大不相同。

那麼,到底應該用 rebase 還是 merge 呢?它們有什麼區別?什麼時候用哪個更合適?

什麼是 Git Merge?

概念解釋

git merge 是 Git 中最常用的分支合併命令。當你使用 merge 命令時,Git 會創建一個新的提交(merge commit),保留了兩個分支的所有歷史記錄。

基本用法

# 切換到目標分支(通常是 main 或 master)
git checkout main

# 合併 feature 分支
git merge feature-branch

實際場景演示

假設我們有這樣一個場景:你在 feature-login 分支上開發登錄功能,同時主分支 main 也有其他同事提交了新代碼。

# 初始狀態
# main:     A---B---C
# feature:      \---D---E

# 執行 merge 後
# main:     A---B---C---F (merge commit)
#               \       /
# feature:       \-D---E

代碼示例:

# 1. 創建並切換到功能分支
git checkout -b feature-login

# 2. 在功能分支上進行開發
echo "登錄功能實現" > login.js
git add login.js
git commit -m "添加登錄功能"

# 3. 切換回主分支
git checkout main

# 4. 模擬其他人的提交
echo "修復了一個 bug" > bugfix.js
git add bugfix.js
git commit -m "修復用户頭像顯示問題"

# 5. 合併功能分支
git merge feature-login

什麼是 Git Rebase?

概念解釋

git rebase 的英文直譯是「變基」,它可以將一個分支的提交「移植」到另一個分支上,使得提交歷史呈現為一條直線,更加清晰整潔。

Rebase 會將當前分支的提交「複製」到目標分支的最新提交之後,然後放棄原來的提交。這樣看起來就像是直接從目標分支的最新提交開始開發的,相當於將需要合併的分支上的提交“重放”到了合併的目標分支上。

基本用法

# 方式一:在功能分支上執行
git checkout feature-branch
git rebase main

# 方式二:直接指定分支
git rebase main feature-branch

實際場景演示

還是用剛才登錄功能的例子:

# rebase 前
# main:     A---B---C
# feature:      \---D---E

# 執行 rebase 後
# main:     A---B---C
# feature:            \---D'---E'

代碼示例:

# 1. 在功能分支上進行 rebase
git checkout feature-login
git rebase main

# 2. 如果有衝突,解決後繼續
git add .
git rebase --continue

# 3. 將變基後的分支合併到主分支(這時會是快進合併)
git checkout main
git merge feature-login  # 這將是一個 fast-forward merge

兩者的核心區別

1. 提交歷史的差異

Merge 的特點:

  • 保留完整的提交歷史
  • 會產生合併提交
  • 分支結構清晰可見
  • 歷史記錄可能比較複雜

Rebase 的特點:

  • 創造線性的提交歷史
  • 不會產生額外的合併提交
  • 看起來更加整潔
  • 會改變提交的 SHA 值

2. 可視化對比

讓我們用一個更直觀的例子來看看:

# 使用 Merge 後的歷史
*   a1b2c3d (HEAD -> main) Merge branch 'feature-login'
|\  
| * d4e5f6g 添加密碼加密功能
| * h7i8j9k 實現用户登錄邏輯
* | k1l2m3n 優化首頁加載速度
* | n4o5p6q 修復導航欄樣式問題
|/  
* q7r8s9t 初始提交

# 使用 Rebase 後的歷史
* f9g8h7i (HEAD -> main) 添加密碼加密功能
* e6f7g8h 實現用户登錄邏輯
* d3e4f5g 優化首頁加載速度
* c2d3e4f 修復導航欄樣式問題
* a1b2c3d 初始提交

什麼時候使用 Merge?

適用場景

  1. 功能分支合併:當你完成一個完整的功能開發時
  2. 團隊協作:多人協作時保留清晰的分支結構
  3. 重要的里程碑:需要明確標記合併點的時候
  4. 開源項目:需要保留貢獻者的提交歷史

實際示例

# 場景:完成用户管理功能的開發
git checkout main
git pull origin main  # 確保主分支是最新的
git merge feature-user-management
git push origin main

# 查看合併歷史
git log --graph --oneline

什麼時候使用 Rebase?

適用場景

  1. 清理提交歷史:在推送到遠程倉庫前整理提交
  2. 同步主分支更新:將主分支的新變更同步到功能分支
  3. 個人開發:在個人分支上工作時
  4. 線性歷史偏好:團隊偏好簡潔的線性歷史

實際示例

# 場景一:同步主分支最新變更
git checkout feature-dashboard
git rebase main  # 將主分支的新提交應用到當前分支

# 場景二:交互式 rebase 清理提交歷史
git rebase -i HEAD~3  # 整理最近 3 次提交

交互式 Rebase 示例

# 執行交互式 rebase
git rebase -i HEAD~3

# 編輯器會顯示類似內容:
pick a1b2c3d 添加用户登錄接口
pick d4e5f6g 修復登錄bug
pick g7h8i9j 添加登錄日誌

# 你可以進行以下操作:
# pick: 保留這個提交
# reword: 保留提交但修改提交信息
# edit: 保留提交但暫停以便修改
# squash: 將這個提交合併到前一個提交
# drop: 刪除這個提交

衝突處理

Merge 衝突處理

# 當出現合併衝突時
git merge feature-branch

# Git 會提示衝突,編輯衝突文件
# 解決衝突後
git add .
git commit  # Git 會自動生成合並提交信息

Rebase 衝突處理

# 當出現 rebase 衝突時
git rebase main

# 解決衝突後
git add .
git rebase --continue

# 如果想放棄 rebase
git rebase --abort

解決衝突的差異

  • Merge 在一次合併提交中解決所有衝突
  • Rebase 可能會在每個被複制的提交處都需要解決衝突

最佳實踐建議

1. 團隊約定

推薦的工作流:

  1. 功能分支開發期間:使用 rebase 同步主分支更新
  2. 功能開發完成後:使用 merge 合併到主分支
  3. 推送前:使用交互式 rebase 清理提交歷史

2. 安全原則

Rebase 的黃金法則:

永遠不要對已經推送到遠程倉庫的提交執行 rebase!
這是因為 rebase 會重寫提交歷史,如果其他人已經基於這些提交進行開發,會導致嚴重的協作問題。

# 永遠不要對已經推送到遠程的提交執行 rebase!
# ❌ 錯誤做法(如果已經推送到遠程)
git rebase main

# ✅ 正確做法
git pull --rebase origin main 
# 或者
git merge main

3. 實用命令組合

# 常用的 rebase 命令
git pull --rebase    # 拉取時使用 rebase 而不是 merge
git config pull.rebase true  # 設置 pull 默認使用 rebase

# 查看分支圖
git log --graph --pretty=oneline --abbrev-commit

# 撤銷上次 merge(如果還沒推送)
git reset --hard HEAD~1

總結

選擇 rebase 還是 merge 並沒有絕對的對錯,關鍵是要根據具體場景和團隊約定來決定:

  • 需要保留完整歷史和分支結構:選擇 merge
  • 希望保持線性、整潔的提交歷史:選擇 rebase
  • 多人協作的公共分支:謹慎使用 rebase
  • 個人開發的功能分支rebase 是很好的選擇

記住,工具本身沒有好壞,關鍵是要理解它們的特點,在合適的場景下使用合適的工具。在團隊協作中,保持一致的使用規範比選擇哪種方式更重要。與團隊成員協商確定適合項目的合併策略,才能讓版本歷史既美觀又實用。

希望本文能幫助你更好地理解和使用 Git 的合併工具。

有什麼問題歡迎在評論區討論,我們一起進步! 🚀

Add a new Comments

Some HTML is okay.