网站首页 > 基础教程 正文
本文档将深入讨论 git rebase 命令。Rebase 命令在设置仓库和重写历史页面中也有涉及。本页将更详细地介绍 git rebase 的配置和执行。这里将涵盖常见的 Rebase 使用场景和注意事项。
Rebase 是 Git 中专门用于将一个分支的更改集成到另一个分支的两个工具之一。另一个更改集成工具是 git merge。Merge 始终是一个向前移动的更改记录。而 rebase 则具有强大的历史重写功能。要详细了解 Merge 与 Rebase 的区别,请访问我们的 Merge vs Rebase 指南。Rebase 本身有两种主要模式:"手动"模式和"交互"模式。我们将在下面详细介绍不同的 Rebase 模式。
什么是 git rebase?
Rebasing 是将一系列提交移动或合并到新的基础提交的过程。Rebasing 在特性分支工作流中最有用且最容易可视化。一般过程可以如下所示:
从内容角度来看,rebase 是将分支的基础从一个提交更改为另一个提交,使其看起来像是从不同的提交创建了分支。在内部,Git 通过创建新的提交并将它们应用到指定的基础来实现这一点。重要的是要理解,即使分支看起来相同,它也是由全新的提交组成的。
使用方法
Rebase 的主要原因是保持项目历史的线性。例如,考虑这样一种情况:自从你开始处理特性分支以来,主分支已经有所进展。你希望将主分支的最新更新获取到你的特性分支中,但你想保持分支历史的整洁,使其看起来像是你一直在最新的主分支上工作。这为以后将特性分支干净地合并回主分支提供了好处。为什么我们要保持"干净的历史"?当执行 Git 操作来调查回归的引入时,拥有干净历史的好处就变得切实可见。一个更现实的场景是:
- 在主分支中发现了一个 bug。一个之前正常工作的功能现在出现了问题。
- 由于"干净的历史",开发人员使用 git log 检查主分支的历史,能够快速理解项目的历史。
- 开发人员无法使用 git log 确定 bug 是何时引入的,因此执行了 git bisect。
- 由于 Git 历史是干净的,git bisect 在寻找回归时有更精确的提交集可以比较。开发人员很快找到了引入 bug 的提交,并能够采取相应措施。
你有两种选择将特性集成到主分支:直接合并或先 rebase 再合并。前一种选择会导致三方合并和合并提交,而后一种选择会导致快进合并和完美的线性历史。下图展示了如何通过 rebase 到主分支来促进快进合并。
Rebase 是将上游更改集成到本地仓库的常用方法。使用 Git merge 拉取上游更改会导致每次你想查看项目进展时都会产生多余的合并提交。另一方面,rebase 就像是说:"我想基于其他人已经完成的工作来应用我的更改。"
不要 rebase 公共历史
正如我们之前在重写历史中讨论的那样,一旦提交被推送到公共仓库,就永远不应该 rebase 这些提交。Rebase 会用新的提交替换旧的提交,看起来就像是项目历史的那部分突然消失了。
Git rebase 标准模式 vs Git rebase 交互模式
Git rebase 交互模式是当 git rebase 接受 -i 参数时。这代表"交互式"。没有任何参数时,命令以标准模式运行。在这两种情况下,假设我们已经创建了一个单独的特性分支。
# 基于主分支创建特性分支
git checkout -b feature_branch main
# 编辑文件
git commit -a -m "添加新特性"
标准模式下的 Git rebase 会自动获取当前工作分支中的提交,并将它们应用到传递的分支的头部。
git rebase <base>
这会自动将当前分支 rebase 到 <base> 上,<base> 可以是任何类型的提交引用(例如 ID、分支名称、标签或 HEAD 的相对引用)。
使用 -i 标志运行 git rebase 会开始一个交互式 rebase 会话。与盲目移动所有提交到新基础不同,交互式 rebase 让你有机会在过程中修改单个提交。这让你可以通过删除、分割和修改现有的一系列提交来清理历史。这就像是 git commit --amend 的加强版。
git rebase --interactive <base>
这会将当前分支 rebase 到 <base> 上,但使用交互式 rebase 会话。这会打开一个编辑器,你可以在其中为每个要 rebase 的提交输入命令(如下所述)。这些命令决定了单个提交将如何转移到新基础。你还可以重新排序提交列表来更改提交本身的顺序。一旦你为 rebase 中的每个提交指定了命令,Git 将开始播放提交,应用 rebase 命令。rebase 编辑命令如下:
pick 2231360 一些旧的提交
pick ee2adc2 添加新特性
# Rebase 2cf755d..ee2adc2 onto 2cf755d (9 个命令)
#
# 命令:
# p, pick = 使用提交
# r, reword = 使用提交,但编辑提交消息
# e, edit = 使用提交,但停止以进行修改
# s, squash = 使用提交,但合并到前一个提交中
# f, fixup = 类似于 "squash",但丢弃此提交的日志消息
# x, exec = 使用 shell 运行命令(行的其余部分)
# d, drop = 删除提交
额外的 rebase 命令
正如重写历史页面中详细说明的那样,rebase 可用于更改较旧和多个提交、已提交的文件和多个消息。虽然这些是最常见的应用,但 git rebase 还有一些额外的命令选项,在更复杂的应用中可能很有用。
- git rebase --d 意味着在播放过程中,提交将从最终组合的提交块中丢弃。
- git rebase --p 保持提交不变。它不会修改提交的消息或内容,并且仍然是分支历史中的单个提交。
- git rebase --x 在播放过程中在每个标记的提交上执行命令行 shell 脚本。一个有用的例子是在特定提交上运行代码库的测试套件,这可能有助于在 rebase 期间识别回归。
总结
交互式 rebase 让你完全控制项目历史的外观。这为开发人员提供了很大的自由,因为它允许他们在专注于编写代码时提交"混乱"的历史,然后在事后清理。
大多数开发人员喜欢在将特性分支合并到主代码库之前使用交互式 rebase 来完善它。这让他们有机会压缩不重要的提交,删除过时的提交,并确保在提交到"官方"项目历史之前一切都井然有序。对其他人来说,看起来整个特性是在一系列精心策划的提交中开发的。
交互式 rebase 的真正威力可以在结果主分支的历史中看到。对其他人来说,看起来你是一个出色的开发人员,第一次就完美地实现了新特性。这就是交互式 rebase 如何保持项目历史的整洁和有意义。
配置选项
有一些 rebase 属性可以使用 git config 设置。这些选项将改变 git rebase 输出的外观和感觉。
- rebase.stat:一个布尔值,默认为 false。该选项切换显示自上次 rebase 以来更改的视觉 diffstat 内容。
- rebase.autoSquash:一个布尔值,用于切换 --autosquash 行为。
- rebase.missingCommitsCheck:可以设置为多个值,这些值会改变 rebase 在缺失提交周围的行为:
- warn:在交互模式下打印警告输出,警告已删除的提交
- error:停止 rebase 并打印已删除提交的警告消息
- ignore:默认设置,忽略任何缺失提交警告
- rebase.instructionFormat:一个 git log 格式字符串,用于格式化交互式 rebase 显示
高级 rebase 应用
命令行参数 --onto 可以传递给 git rebase。在 git rebase --onto 模式下,命令扩展为:
git rebase --onto <newbase> <oldbase>
--onto 命令启用了一种更强大的 rebase 形式,允许传递特定的引用作为 rebase 的尖端。假设我们有一个示例仓库,分支如下:
o---o---o---o---o main
\
o---o---o---o---o featureA
\
o---o---o featureB
featureB 基于 featureA,然而,我们意识到 featureB 不依赖于 featureA 的任何更改,可以直接从 main 分支出来。
git rebase --onto main featureA featureB
featureA 是 <oldbase>。main 成为 <newbase>,featureB 是 <newbase> 的 HEAD 指向的引用。结果如下:
o---o---o featureB
/
o---o---o---o---o main
\
o---o---o---o---o featureA
理解 rebase 的危险
在使用 Git Rebase 时需要考虑的一个警告是,在 rebase 工作流中合并冲突可能会更频繁地发生。如果你有一个长期存在的分支与主分支偏离,就会发生这种情况。最终你会想要对主分支进行 rebase,那时它可能包含许多新的提交,你的分支更改可能会与之冲突。通过频繁地对主分支进行 rebase 和更频繁地提交,这很容易解决。--continue 和 --abort 命令行参数可以传递给 git rebase,以在处理冲突时推进或重置 rebase。
一个更严重的 rebase 警告是交互式历史重写中丢失的提交。在交互模式下运行 rebase 并执行 squash 或 drop 等子命令会从分支的立即日志中删除提交。乍一看,这似乎像是提交永久消失了。使用 git reflog 可以恢复这些提交,并且可以撤销整个 rebase。有关使用 git reflog 查找丢失提交的更多信息,请访问我们的 Git reflog 文档页面。
Git Rebase 本身并不严重危险。真正的危险情况出现在执行历史重写交互式 rebase 并将结果强制推送到其他用户共享的远程分支时。应该避免这种模式,因为它有可能在用户拉取时覆盖其他远程用户的工作。
从上游 rebase 中恢复
如果另一个用户已经 rebase 并强制推送到你正在提交的分支,git pull 将用强制推送的尖端覆盖你基于该先前分支的任何提交。幸运的是,使用 git reflog 你可以获取远程分支的 reflog。在远程分支的 reflog 中,你可以找到它被 rebase 之前的引用。然后你可以使用 --onto 选项将你的分支 rebase 到该远程应用上,如上面高级 Rebase 应用部分所述。
总结
在本文中,我们介绍了 git rebase 的用法。我们讨论了基本和高级用例以及更高级的示例。一些关键的讨论点是:
- git rebase 标准模式与交互模式
- git rebase 配置选项
- git rebase --onto
- git rebase 丢失的提交
- 上一篇: 计算机知识 | Git版本控制流程
- 下一篇: git命令行打tag基础知识
猜你喜欢
- 2025-04-28 使用 Git 命令去管理项目的版本控制(二)
- 2025-04-28 腾讯云国际站代理商:如何搭建Git服务器?
- 2025-04-28 拯救你的 Git 仓库!用 BFG 秒删历史大文件,告别迁移失败
- 2025-04-28 用git rebase命令合并开发阶段中多条commit提交记录
- 2025-04-28 git命令行打tag基础知识
- 2025-04-28 计算机知识 | Git版本控制流程
- 2025-04-28 计算机知识 | 在工作流中常用的Git命令
- 2025-04-28 如何完整迁移 Git 仓库 ?
- 2025-04-28 日常开发中常用的git操作命令和使用技巧
- 2025-04-28 Git下载安装以及必须知道的Git常用指令
- 04-28使用 Git 命令去管理项目的版本控制(二)
- 04-28腾讯云国际站代理商:如何搭建Git服务器?
- 04-28拯救你的 Git 仓库!用 BFG 秒删历史大文件,告别迁移失败
- 04-28用git rebase命令合并开发阶段中多条commit提交记录
- 04-28git命令行打tag基础知识
- 04-28Git Rebase
- 04-28计算机知识 | Git版本控制流程
- 04-28计算机知识 | 在工作流中常用的Git命令
- 最近发表
- 标签列表
-
- 菜鸟教程 (58)
- jsp (69)
- c++教程 (58)
- pythonlist (60)
- gitpush (78)
- pythonif (68)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)