Git代码合并之使用 rebase 整理提交历史
Git 中整合來自不同分支的修改有兩種方式:git merge?和?git rebase。本文主要介紹?rebase?的3種使用場景:
場景1: 使用?rebase?合并分支--整合分叉的提交歷史
-
場景2: 壓縮提交歷史
-
場景3: 修改多個提交信息
1 使用 rebase 合并分支
1.1 場景描述
我們在?feature?分支開發完新的功能后,通常會通過?merge?操作將代碼合并到?master?分支,這樣會產生一條分叉。這時可以通過變基使得提交歷史更加整潔,看上去就像是串行的一樣,提交歷史是一條直線沒有分叉。
1.2 操作命令
首先在自己的?feature?分支里進行開發,當開發完成時你需要先將你的代碼變基到?master?上,然后再向?master?分支提交修改。 這樣的話,該項目的維護者就不再需要進行整合工作,只需要快進合并便可。具體操作如下:
#?1?變基到?master git?checkout?feature git?rebase?master#?2?回到?master?分支,進行一次快進合并。 git?checkout?master git?merge?feature1.3 原理圖解
假設在你的項目上?master?分支的提交為?C0、C1、C2、C3,基于?master?的?C2?節點拉出了一個?feature?分支,并產生了新的提交C4,如下圖:
16-1
整個變基操作的過程如下圖所示,首先找到這兩個分支(即當前分支?feature、變基操作的目標基底分支?master) 的最近共同祖先?C2,然后對比當前分支相對于該祖先的歷次提交,提取相應的修改并存為臨時文件, 然后將當前分支(feature)指向目標基底?C3, 最后以此將之前另存為臨時文件的修改依序應用,此時?feature?指向?C4',如下圖:
最后回到?master?分支,進行一次快進合并,完成后?feature?和?master?分支均指向?C4',如下圖:
16-3
至此合并分支操作完成,master?的提交歷史是一條干凈的、沒有分叉的直線。
2 使用 交互式的 rebase
通過給?git rebase?增加?-i?選項來交互式地運行變基。 一般被用于將?feature?分支并入?master?分支之前,清理混亂的提交歷史。
2.1 壓縮提交歷史
2.1.1 場景描述
覺得?commit?太小太散,將多個?commit?壓縮成一個單獨的提交。
2.1.2 操作命令
假設將?feature?分支當前最近的3個提交變為一個提交,操作如下:
#?1.執行交互式?rebase git?rebase?-i?HEAD~3 #?或使用如下命令 git?rebase?-i?dbcc8dd?#?dbcc8dd?為與?HEAD~3?對應的?commitid#?2.進入編輯器,將16.md-2、16.md-3?的?pick?改為?squash,代表想要把它們跟上一個?commit(16.md-1)合并? pick?fe08362?feat:?update?16.md-1 squash?72a7fae?feat:?update?16.md-2 squash?f606aec?feat:?update?16.md-3#?3.第2步保存并退出編輯器后看到如下畫面 feat:?add?file?16.md?#?刪除原本的?commit?message,?改為自己想要的提交信息 #?Please?enter?the?commit?message?for?your?changes.?Lines?starting #?with?'#'?will?be?ignored,?and?an?empty?message?aborts?the?commit. # #?Date:??????Wed?Aug?3?20:00:18?2022?+0800 # #?interactive?rebase?in?progress;?onto?dbcc8dd #?Last?commands?done?(3?commands?done): #????squash?72a7fae?feat:?update?16.md-2 #????squash?f606aec?feat:?update?16.md-3 #?No?commands?remaining. #?You?are?currently?rebasing?branch?'master'?on?'dbcc8dd'.#?4.操作完成,驗證結果 git?log注意上述第2步中的反序顯示。 交互式變基給你一個它將會運行的腳本。 它將會從你在命令行中指定的提交(HEAD~3)開始,從上到下的依次重演每一個提交引入的修改。 它將最舊的而不是最新的列在上面,因為那會是第一個將要重演的。
2.2 修改多個提交信息
2.2.1 場景描述
修改在提交歷史中的提交信息。
2.2.2 操作命令
例如要修改?feature?分支最近三次的提交中的任意一個提交信息。
#?1.執行交互式?rebase git?rebase?-i?HEAD~3#?2.進入編輯器,將要被修改信息的提交由?pick?改為?reword,代表要修改16.md-1的提交信息 reword?fe08362?feat:?update?16.md-1 pick?72a7fae?feat:?update?16.md-2 pick?f606aec?feat:?update?16.md-3#?3.第2步保存并退出編輯器后看到如下畫面 修改后的提交信息feat:?update?16.md-1?#?刪除原本的?commit?message,?改為自己想要的提交信息 #?Please?enter?the?commit?message?for?your?changes.?Lines?starting #?with?'#'?will?be?ignored,?and?an?empty?message?aborts?the?commit. # #?Date:??????Thu?Aug?18?16:34:55?2022?+0800 # #?interactive?rebase?in?progress;?onto?dbcc8dd #...#?4.操作完成,驗證修改結果 git?log2.3 其它的一些操作
除了2.1、2.2的使用場景外,交互式的?rebase?還可以?調整commit順序、刪除 commit?等,操作過程與2.1、2.2大同小異,具體可參考如下指令:
#?Commands: #?p,?pick?<commit>?=?use?commit #?r,?reword?<commit>?=?use?commit,?but?edit?the?commit?message #?e,?edit?<commit>?=?use?commit,?but?stop?for?amending #?s,?squash?<commit>?=?use?commit,?but?meld?into?previous?commit #?f,?fixup?<commit>?=?like?"squash",?but?discard?this?commit's?log?message #?x,?exec?<command>?=?run?command?(the?rest?of?the?line)?using?shell #?b,?break?=?stop?here?(continue?rebase?later?with?'git?rebase?--continue') #?d,?drop?<commit>?=?remove?commit #?l,?label?<label>?=?label?current?HEAD?with?a?name #?t,?reset?<label>?=?reset?HEAD?to?a?label #?m,?merge?[-C?<commit>?|?-c?<commit>]?<label>?[#?<oneline>] #?.???????create?a?merge?commit?using?the?original?merge?commit's #?.???????message?(or?the?oneline,?if?no?original?merge?commit?was #?.???????specified).?Use?-c?<commit>?to?reword?the?commit?message.3 注意事項
使用 rebase 得遵守一條準則:
如果提交存在于你的倉庫之外,而別人可能基于這些提交進行開發,那么不要執行變基。
換句話說,因為?rebase?會變更歷史記錄,所以最好是在?push?之前就做好?rebase,不然就是確保要這個?branch?只有你自己在修改,否則你也?rebase、他也?rebase,最后只會把歷史記錄搞得一團糟。
4 參考資料
Git 官方文檔
送 PR 前,使用 Git rebase 來整理你的 commit 吧!
總結
以上是生活随笔為你收集整理的Git代码合并之使用 rebase 整理提交历史的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 人力资源管理系统面向对象建模分析
- 下一篇: 蚂蚁开放平台开发第三方授权登陆(二):P