【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.

变基前后示意图如下:

相关推荐
巴伦是只猫10 分钟前
【深度学习笔记】2 浅层神经网络
笔记·深度学习·神经网络
没有羊的王K12 分钟前
SSM框架学习DI入门——day2
java·spring boot·学习
公子绝12 分钟前
JAVA学习笔记 使用notepad++开发JAVA-003
java·学习·notepad++·java开发环境
wb18916 分钟前
LVS的集群技术和分布式
运维·笔记·分布式·云计算·lvs
本杰明15222 分钟前
2025/7/14——java学习总结
java·开发语言·学习
ysa05103040 分钟前
竞赛常用加速技巧#模板
c++·笔记·算法
特种加菲猫2 小时前
硬件与软件的桥梁:冯诺依曼体系、操作系统和初始进程的深度解析
linux·笔记
LGGGGGQ4 小时前
嵌入式学习-PyTorch(4)-day21
学习
艾莉丝努力练剑5 小时前
【LeetCode&数据结构】单链表的应用——反转链表问题、链表的中间节点问题详解
c语言·开发语言·数据结构·学习·算法·leetcode·链表
人生游戏牛马NPC1号6 小时前
学习 Flutter (三):玩安卓项目实战 - 上
android·学习·flutter