发布于 2026-01-06 6 阅读
0

面向未来!DEV 全球展示挑战赛,由 Mux 呈现:展示你的项目!

面向未来!

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

虽然变基本身并不是一个复杂的概念,但很多人却难以理解它。

我认为这主要是因为 Git 新手往往会推迟或根本没时间学习 rebase 命令,因为他们被 Git 的其他各种基础知识搞得焦头烂额。而且,他们不断听到 rebase 是个危险的命令,这更让他们迟迟不愿学习。

如果这也适用于你,那就跟着我一起通过一个简单的例子来学习git rebase的工作原理吧。


假设你当前位于项目的master分支上(我们仅显示最近的 4 次提交):

主分支

现在你想在另一个分支上开发一些很酷的新功能,所以你创建了一个分支git checkout -b feature并提交了两次。现在你的分支masterfeature分支看起来是这样的:

特性分支

但现在有人报告了你的应用程序存在一个 bug,你迅速切换到自己的master分支去查找并修复它。过了一段时间,你修复了 bug 并推送(部署)了更改。一切恢复正常,你可以回到你的feature分支了。

错误修复

但现在你意识到遇到了一点小问题。你的feature分支仍然存在你在主分支上修复的那个 bug master,而且你意识到这个 bug 也会影响你在主feature分支上的新代码,所以你需要把修复 bug 的更改(提交)合并到你的feature主分支上。但是该怎么做呢?嗯,有几种方法可以做到,但最好的方法是像 Doc 和 Marty 那样回到过去,在创建分支之前提交修复 bug 的更改feature。这样,包含修复 bug 代码的提交就会被包含在你的feature主分支中(当你回到未来之后)。实际上,你可以做到这一点。我的意思是,不是真的回到过去,而是修改(git)历史记录。你可以使用 rebase 命令来实现。所以,如果你在你的feature主分支上,然后执行以下操作:

git rebase master
Enter fullscreen mode Exit fullscreen mode

这就是修剪后树枝的样子:

错误修复

如您所见,分支的历史记录feature已发生改变。如果有人现在查看该分支,他/她会认为您是feature在提交修复 bug 的命令之后创建(检出)的。


所以这很棒,对吧?为什么不一直用它呢?嗯,这里有个小问题。还记得Doc和Marty回到未来时,世界有点不一样吗?git rebase也会出现这种情况,但别担心,你的代码不会改变,只有feature分支上提交的校验和会发生变化。这些校验和是什么呢?你可能已经注意到,每次提交时,都会在旁边显示一个40个字符长的字符串git log

commit f5cad47722bc98419fe5037753f5bbe29d3917c4
Author: John Doe <john@doe.com>
Date:   Mon Apr 23 11:49:07 2018 +0200

Did some stuff:)
Enter fullscreen mode Exit fullscreen mode

这就是校验和。你可以把校验和理解为提交的唯一标识符,由于 Git 生成校验和的方式(你可以查看我关于 Git数据模型的博客文章了解更多信息),它们feature在变基后会在我们分支上发生变化。

因此,如果变基之前提交的校验和如下:
重新定基前的校验和

变基之后,feature分支上的校验和会发生变化:
重新定基后的校验和

这就是为什么你总是听到“git rebase”是一个危险的命令。因为它会改变历史记录,所以你应该谨慎使用。

但究竟为什么这样做很危险?什么时候会危险呢?假设你不是唯一一个在feature分支上工作的人,还有其他人也在拉取和推送更改。现在你执行了变基操作,并(强制)将更改推送到feature远程仓库。这时,当你的同事 Bob 尝试从远程仓库拉取更改时feature,就会出现问题,因为他本地分支的feature历史记录与远程分支不同。

重新基准爆炸
好吧,鲍勃的电脑不会真的爆炸,但他也没有什么好办法解决这个问题。所以,一般来说,如果你正在一个公共分支(其他人会从中拉取更改)上工作,就不要在这个分支上进行变基操作。但如果你正在本地分支上工作,并且还没有将其推送到远程服务器,或者你已经推送了但目前只有你一个人在这个分支上工作(你必须确定这一点),那么你就可以在这个分支上进行变基操作。

文章来源:https://dev.to/konrad_126/rebase-to-the-future-13j9