【Git 学习笔记】第四章 git rebase 变基操作与相关示例(上)

文章目录

  • [第四章 变基操作及相关案例](#第四章 变基操作及相关案例)
    • [4.0 变基简介](#4.0 变基简介)
    • [4.1 将 `commit` 版本变基到另一分支](#4.1 将 commit 版本变基到另一分支)
    • [4.2 在版本冲突的情况下执行变基](#4.2 在版本冲突的情况下执行变基)
    • [4.3 对指定版本执行交互式变基](#4.3 对指定版本执行交互式变基)

第四章 变基操作及相关案例

【相关主题】

  • commit 版本变基到另一分支
  • 在版本冲突的情况下执行变基
  • 对指定版本执行交互式变基
  • 利用交互式变基聚合版本
  • 利用交互式变基变更提交者
  • 自动聚合版本

4.0 变基简介

变基(Rebasing)是 Git 具备的一个异常强大的特性。变基是这样一类操作:假如一个 commit A 最早是基于 commit B 的;那么将 A 变基到 C ,就是将 A 变为基于 C 的操作。

在接下来的演示案例中,你会发现变基操作往往并不像看上去那么容易。

4.1 将 commit 版本变基到另一分支

先来看看最简单的一类变基操作。相关准备工作:引入一个新文件、提交、变更内容、再提交。这样本地就有了两次 commit 版本。

还是以 jgit 库为例:

bash 复制代码
# Clone jgit repo into chapter4
$ git clone https://git.eclipse.org/r/jgit/jgit chapter4
$ cd chapter4
# Checkout a new branch
$ git checkout -b rebaseExample --track origin/stable-3.1
# Create the 1st commit
$ echo "My Fishtank
    
Gravel, water, plants
Fish, pump, skeleton" > fishtank.txt
$ git add fishtank.txt
$ git commit -m "My brand new fishtank"
# Create the 2nd commit
$ echo "mosquitos" >> fishtank.txt
$ git add fishtank.txt
$ git commit -m "Feeding my fish"
# Rabase to stable-3.2
$ git rebase origin/stable-3.2
Successfully rebased and updated refs/heads/rebaseExample.

变基前:

变基后:

git rebase 的执行过程:

  1. 找到 HEAD 与变基指向的目标分支之间的公共版本(merge-base);
  2. 基于 merge-base,找出目标分支上所有缺少的版本;
  3. 尝试将缺少的版本逐一应用到目标分支上。

4.2 在版本冲突的情况下执行变基

如果将一个 commit 版本或一个 branch 分支变基到不同的 HEAD 上,很可能会出现版本冲突。此时必须解决完冲突,并运行命令 git rebase --continue,方可完成变基。

本节示例将演示如何在有冲突的情况下完成变基。沿用 4.1 节中演示的最终结果,此时 rebaseExample 分支已经变基到 stable-3.2 分支。示例将从 stable-3.1 重新检出新分支,并添加一个和 rebaseExample 分支同名但内容不容的文本文件 fishtank.txt

bash 复制代码
# Checkout rebaseExample2
$ git checkout -b rebaseExample2 --track origin/stable-3.1
# Add a new commit
$ echo "My Fishtank
Pirateship, Oister shell
Coconut shell
">fishtank.txt
$ git add fishtank.txt
$ git commit -m "My brand new fishtank"
# Rebase conflicting branches
$ git rebase rebaseExample
Auto-merging fishtank.txt
CONFLICT (add/add): Merge conflict in fishtank.txt
error: could not apply 24f9bf1ef... My brand new fishtank2
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 24f9bf1ef... My brand new fishtank2
$ subl fishtank.txt

冲突情况如下:

改为如下内容后保存、关闭:

添加合并好的文件,继续变基:

bash 复制代码
$ git add fishtank.txt
$ git rebase --continue
hint: Waiting for your editor to close the file...

打开的编辑器如图所示:

确认、保存并关闭,将看到提示变基成功:

bash 复制代码
$ git rebase --continue
[detached HEAD 9911772b3] My brand new fishtank2
 1 file changed, 2 insertions(+), 3 deletions(-)
Successfully rebased and updated refs/heads/rebaseExample2.
# Check new status via gitk
$ gitk

详情如下:

可见,本次变基,只将旧分支有、而新分支没有的版本变基过来(即新增 commit)。

在首次变基中断的 git 提示信息中,还能看到两个备选项:

  1. git rebase --abort:如字面含义,中断变基

  2. git rebase --skip:跳过冲突直接变基,这将导致 rebaseExample2 放弃新增的 commit,直接并入 rebaseExample,变基后指向的父级,和 rebaseExample 一致:


4.3 对指定版本执行交互式变基

本例以 4.1 中的 rebaseExample 分支为基础,演示如何利用 --interactive 标记,将 4.1 中变基的两个 commit 重新变基到远程跟踪分支 stable-3.1 上:

bash 复制代码
$ git checkout rebaseExample
Switched to branch 'rebaseExample'
Your branch is ahead of 'origin/stable-3.1' by 109 commits.
  (use "git push" to publish your local commits)
$ git rebase origin/stable-3.1

此时在新弹出的编辑器中会展示一个 commit 列表,范围是 rebaseExamplestable-3.1 之间的、所有可以变基到 stable-3.1commit 记录。保留示例中新增的两个 commit,其余全部删除(即第 89 行及以前的内容):

保存后退出编辑器可以看到如下输出:

bash 复制代码
$ git rebase --interactive origin/stable-3.1
Successfully rebased and updated refs/heads/rebaseExample.
# Check in gitk view:

结果如下:

示例拓展

本例还可以通过一个命令快速实现既定效果:

bash 复制代码
$ git rebase --onto origin/stable-3.1 origin/stable-3.2 rebaseExample
Successfully rebased and updated refs/heads/rebaseExample.

变基前后示意图如下:

相关推荐
Red Red18 分钟前
网安基础知识|IDS入侵检测系统|IPS入侵防御系统|堡垒机|VPN|EDR|CC防御|云安全-VDC/VPC|安全服务
网络·笔记·学习·安全·web安全
贰十六1 小时前
笔记:Centos Nginx Jdk Mysql OpenOffce KkFile Minio安装部署
笔记·nginx·centos
知兀1 小时前
Java的方法、基本和引用数据类型
java·笔记·黑马程序员
Natural_yz2 小时前
大数据学习17之Spark-Core
大数据·学习·spark
qq_172805592 小时前
RUST学习教程-安装教程
开发语言·学习·rust·安装
一只小小汤圆2 小时前
opencascade源码学习之BRepOffsetAPI包 -BRepOffsetAPI_DraftAngle
c++·学习·opencascade
醉陌离2 小时前
渗透测试笔记——shodan(4)
笔记
虾球xz2 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
LateBloomer7773 小时前
FreeRTOS——信号量
笔记·stm32·学习·freertos