網站首頁 編程語言 正文
Git 中整合來自不同分支的修改有兩種方式:git merge
?和?git rebase
。本文主要介紹?rebase
?的3種使用場景:
-
場景1: 使用?
rebase
?合并分支--整合分叉的提交歷史 - 使用?
交互式的 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?feature
1.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?log
2.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 吧!
原文鏈接:https://blog.csdn.net/m0_63524561/article/details/126414500
相關推薦
- 2022-03-19 linux修改文件所屬用戶和組的實例方法_Linux
- 2022-04-16 C++順序表的基本操作實現_C 語言
- 2022-08-05 python內置模塊之上下文管理contextlib_python
- 2022-03-07 Go中defer使用場景及注意事項_Golang
- 2022-05-18 ASP.NET?MVC實現區域路由_實用技巧
- 2022-04-08 Unity?UGUI?按鈕綁定事件的?4?種方式匯總_C#教程
- 2022-04-28 Pytorch中torch.flatten()和torch.nn.Flatten()實例詳解_pyt
- 2022-07-30 find、filter、map的區別
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支