0x0 引言
網絡上關於 git rebase 使用的教程不少,其中一篇把遠端操作混入了進來,繪制的 commit tree 放了 hash 碼也導致亂亂的,個人覺得不妥。git rebase 的理解應該是和遠端獨立的,用1~2個數字和字母來替代 hash 碼會更加直觀;同時結合了 git kraken 這一 GUI 軟件進行實踐,記錄如下。
0x1 git merge 是怎樣合並分支的
假設 main 分支有 M1, M2 兩個 commit 節點,分支 boxfilter 是基於 M2 節點派生出來,后續創建了 B1 和 B2 節點完成 boxfilter 功能的開發,現在打算把 B1 B2 合並到 main 分支的 M4 節點之后:
最直接的方法是使用 git merge 命令:
git checkout main
git merge boxfilter
或者,在 GitKraken 軟件中把 boxfilter 分支拖拽到 main 分支上,選擇 "merge boxfilter into main"。總之,會生成一個新的節點:
0x2 git rebase 是怎么合並分支的
實際上可以避免 merge 節點的產生;它本身並沒有什么意義;用 git rebase 替代 git merge 可以達成這樣的目標(實際上 rebase 后還需要額外執行一些操作,才是完全的“不創建新節點的合並”)。
具體說來,首先是 git rebase:把 boxfilter 分支上的 B1、B2節點剝下來放到臨時區,讓 boxfilter 分支的拿到 M3、M4 的連接信息,然后從臨時區把 B1、B2 連接到 M4 后面:
git rebase main boxfilter
# 這條命令等價於:
# git checkout boxfilter
# git rebase main
# 如果發生沖突,手動解決后需要執行 git rebase --continue
注意:此時對於 boxfilter 分支來說是發生了變化,是塞入了 M3、M4;對於 main 分支來說並沒有變化。不過由於 main 分支和 boxfilter 已經是一條線,可以快速合並(不會創建新節點),因此執行:
git checkout main
git merge boxfilter --ff-only
或者在 GitKraken 圖形界面工具中,把 boxfilter 分支拖拽到 main 分支,選擇 "fast-forward main to boxfilter"。則得到的 commit tree 中的變化是,main 分支快進到 B2 節點,完成 “不創建新節點的 merge”:
0x3 進一步的操作
到這里,已經完成了干凈的分支合並,並且只依賴於本地操作。
進一步,還可以推送 main 分支到遠端,以及 刪除 boxfilter 分支,刪除 boxfilter 對應的遠程分支(如果存在跟蹤的遠程分支的話)。具體命令為:
git push origin main
git br -D boxfilter
git push --delete origin boxfilter
總結
本文是對 git rebase 用於分支操作的基本用法講解,用 commit tree 的變化圖,直觀的展示了基本原理。涉及到的命令匯總如下:
# 把 main 分支里比 boxfilter 分支多出來的東西,塞到 boxfilter 尾巴節點之前
# 看起來就像是把 boxfilter 分支的東西,接到 main 分支上;但這時 main 分支不受影響
git rebase main boxfilter
# 這里可能要解決沖突,解決后要 git rebase --continue
# 這里可能覺得 boxfilter 分支尾巴節點過多,希望合並
# 則執行 git rebase -i xxx ,然后 squash
# 切換到 main 分支,以快速前進方式,合並 boxfilter 分支
git checkout main
git merge boxfilter --ff-only
# 可選;推送 main 分支到 remote
git push
# 可選;刪除本地分支
git br -D boxfilter
# 可選;刪除遠程分支
git push origin --delete boxfilter