Git rebase:你需要知道的一切

已发表: 2022-12-15
蓝色背景上显示 Linux 命令提示符的笔记本电脑。
fatmawati achmad zaenuri/Shutterstock.com
Git rebase 命令将一个分支移动到另一个分支头部的新位置。 与 Git 合并命令不同,rebase 涉及重写项目历史记录。 这是一个很棒的工具,但不要 rebase 其他开发人员基于其工作的提交。

Git rebase命令将两个源代码分支合并为一个。 Git merge命令也这样做。 我们解释了rebase的作用、它的使用方式以及何时使用merge

目录

Git 爆炸式增长
什么是 Git 合并?
什么是 Git 变基?
如何变基到另一个分支
Git Rebase 与 Merge:您应该使用哪一个?
变基,还是不变基?

Git 爆炸式增长

由于对其他版本控制系统及其缓慢的更新和提交感到沮丧,以 Linux 内核闻名的 Linus Torvalds 在 2005 年抽出一个月的时间来编写自己的版本。 他将其命名为 Git。

GitHub、GitLab 和 BitBucket 等站点共生地促进了 Git 并从中受益。 今天 Git 在全球范围内使用,在 2022 年的一项调查中,71,000 名受访者中有 98% 使用 Git 作为版本控制系统。

Git 的主要设计决策之一是速度。 特别是,与分支机构的合作必须尽可能快。 分支是版本控制系统的基本组成部分。 项目存储库将有一个主分支或主分支。 这是项目代码库所在的位置。 诸如新功能之类的开发在隔离的侧分支中进行。 这可以防止在分支中完成的工作弄乱主分支,并且允许在代码库的不同部分同时进行开发。

如何选择适合您团队的 Git 工作流和分支模型
相关如何选择适合您团队的 Git 工作流和分支模型

随着侧分支中的开发完成,通过将开发分支合并到主分支,将更改转移到主分支。 在其他版本控制系统中,使用分支是困难的,而且计算量大。 在 Git 中使用分支非常快,而且非常轻量级。 在其他系统中曾经是乏味且经常避免的练习,在 Git 中变得微不足道。

Git rebase命令是另一种将更改从一个分支转移到另一个分支的方法。 mergerebase命令具有相似的目标,但它们以不同的方式实现目的并产生略有不同的结果。

什么是 Git 合并?

那么 Git merge命令是做什么用的呢? 假设您创建了一个名为dev-branch来处理一项新功能。

一个 master 分支和一个名为 dev-branch 的未合并分支的图
戴夫·麦凯/How-To-Geek

您进行了一些提交,并测试了您的新功能。 一切正常。 现在您想将新功能发送到master分支。 您必须在master分支中才能将另一个分支合并到它。

我们可以通过在合并之前明确检查它来确保我们在master分支中。

 git结帐大师

我们现在可以告诉 Git 将dev-branch合并到当前分支,即master分支。

 git 合并开发分支

将dev-branch分支合并到master分支

我们的merge已经为我们完成了。 如果你检出master分支并编译它,它就会有新开发的功能。 Git实际执行的是三向合并。 它比较masterdev-branch分支中的最新提交,以及master分支中紧接在dev-branch创建之前的提交。 然后它在master分支上执行提交。

合并被认为是非破坏性的,因为它们不会删除任何内容,也不会更改任何 Git 历史记录。 dev-branch仍然存在,之前的提交都没有改变。 创建一个新的提交来捕获三向合并的结果。

合并后,我们的 Git 存储库看起来像一个时间线,其中有一条备用线分支,然后返回到主时间线。

dev-branch 分支与 master 分支合并
戴夫·麦凯/How-To Geek

dev-branch分支已经并入master分支。

如果您在一个项目中有很多分支,项目的历史就会变得混乱。 如果一个项目有很多贡献者,通常就是这种情况。 因为开发工作分成许多不同的路径,所以开发历史是非线性的。 如果分支有自己的分支,理清提交历史变得更加困难。

Git 分支如何工作?
相关Git 分支如何工作?

请注意,如果您在master分支中有未提交的更改,则需要先对这些更改执行一些操作,然后才能将任何内容合并到其中。 您可以创建一个新分支并在那里提交更改,然后进行合并。 然后,您需要将临时分支合并回主分支。

这行得通,但 Git 有一个命令可以实现同样的事情,而无需创建新的分支。 stash命令为您存储未提交的更改,并允许您使用stash pop回调它们。

你会像这样使用它们:

 藏

git 合并开发分支

藏流行音乐

最终结果是一个合并的分支,其中恢复了未保存的更改。

什么是 Git 变基?

Git rebase命令以完全不同的方式实现了它的目标。 它从你要变基的分支中获取所有提交,并将它们重播到你要变基的分支的末尾。

以我们之前的例子为例,在我们执行任何操作之前,我们的 Git 存储库看起来像这样。 我们有一个名为dev-branch ,我们想将这些更改移动到master分支。

一个 master 分支和一个名为 dev-branch 的未合并分支的图
戴夫·麦凯/How-To-Geek

rebase之后,它看起来像是一个单一的、完全线性的变化时间线。

master 分支与 dev-branch rebased on it
戴夫·麦凯/How-To Geek

dev-branch已被移除, dev-branch -branch 中的提交已添加到 master 分支。 最终结果就像dev-branch中的提交实际上首先直接提交到master分支一样。 提交不只是附加到master分支上,它们被“重放”并重新添加。

这就是rebase命令被认为具有破坏性的原因。 rebased 分支不再作为单独的分支存在,并且项目的 Git 历史已被重写。 您无法在稍后确定哪些提交最初是对dev-branch进行的。

然而,它确实给您留下了一个简化的、线性的历史。 与具有数十个甚至数百个分支和合并的存储库相比,阅读 Git 日志或使用图形化 git GUI 查看存储库的图形,重新设置的存储库很容易理解。

如何变基到另一个分支

让我们尝试一个git rebase示例。 我们有一个项目有一个名为new-feature的分支。 我们会rebase这样将该分支重新定位到master分支。

首先,我们检查master分支没有未完成的更改。

 混帐状态

我们检查new-feature分支。

 git checkout 新功能

我们告诉 Git 将当前分支rebase到 master 分支。

 git 变基大师

我们可以看到我们仍然有两个分支。

 分支

我们交换回master分支

git结帐大师

我们将新功能分支合并到当前分支,在我们的例子中是master分支。

 git 合并新功能
具有新功能的主分支重新基于它
戴夫·麦凯/How-To Geek

有趣的是,最终合并后我们仍然有两个分支。

使用 Git branch 命令列出 git 仓库中的分支
戴夫·麦凯/How-To Geek

不同的是,现在new-feature分支的头部和master分支的头部被设置为指向同一个提交,并且 Git 历史没有显示曾经有一个单独new-feature分支,除了分支标签。

master 分支与 dev-branch rebased on it
戴夫·麦凯/How-To Geek

Git Rebase 与 Merge:您应该使用哪一个?

这不是rebasemerge的情况。 它们都是功能强大的命令,您可能会同时使用它们。 也就是说,在某些用例中, rebase并不能很好地工作。 使用merge的错误导致的取消选择错误令人不快,但是rebase导致的取消选择错误是地狱般的。

如果您是唯一使用存储库的开发人员,那么您使用rebase做一些灾难性的事情的可能性就会降低。 例如,您仍然可以在错误的方向上rebase基,并将您的 master 分支rebase到您的new-feature分支上。 要恢复您的master分支,您需要再次rebase ,这次是从您的new-feature分支到您的master分支。 这将恢复您的master分支,尽管历史看起来很奇怪。

不要在其他人可能工作的共享分支上使用rebase 。 当您将重新设置基础的代码推送到远程存储库时,您对存储库的更改会给很多人带来问题。

如果你的项目有多个贡献者,安全的做法是只在你的本地存储库上使用rebase ,而不是在公共分支上。 同样,如果拉取请求构成代码审查的一部分,请不要使用rebase 。 或者至少,在创建拉取请求后不要使用rebase 。 其他开发人员可能正在查看您的提交,这意味着这些更改位于公共分支上,即使它们不在master分支上也是如此。

危险在于您要对已经推送到远程存储库的提交进行rebase ,而其他开发人员可能已经基于这些提交进行了工作。 您的本地rebase将使那些现有的提交消失。 如果您将这些更改推送到存储库,您将不会受到欢迎。

如何修复、编辑或撤消 Git 提交(更改 Git 历史记录)
相关如何修复、编辑或撤消 Git 提交(更改 Git 历史记录)

其他贡献者将不得不通过混乱的merge才能将他们的工作推回存储库。 如果您随后将他们的更改拉回到您的本地存储库,您将面临取消挑选一堆重复更改的麻烦。

变基,还是不变基?

在你的项目中, Rebase可能是非法的。 可能存在当地的文化异议。 一些项目或组织将rebase视为异端和亵渎行为的一种形式。 有些人认为 Git 历史应该是不可侵犯的、永久的记录所发生的事情。 因此, rebase可能不在讨论之列。

但是,在本地使用,在私有分支上, rebase是一个有用的工具。

在你 rebase之后推送,并将它限制在你是唯一开发人员的分支上。 或者至少,所有开发都已停止,并且没有其他人基于您分支机构的提交开展任何其他工作。

这样做,您将避免任何问题。

相关:如何检查和更新你的 Git 版本