Git rebase:你需要知道的一切
已发表: 2022-12-15
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 rebase命令是另一种将更改从一个分支转移到另一个分支的方法。 merge和rebase命令具有相似的目标,但它们以不同的方式实现目的并产生略有不同的结果。
什么是 Git 合并?
那么 Git merge命令是做什么用的呢? 假设您创建了一个名为dev-branch来处理一项新功能。

您进行了一些提交,并测试了您的新功能。 一切正常。 现在您想将新功能发送到master分支。 您必须在master分支中才能将另一个分支合并到它。
我们可以通过在合并之前明确检查它来确保我们在master分支中。
git结帐大师
我们现在可以告诉 Git 将dev-branch合并到当前分支,即master分支。
git 合并开发分支

我们的merge已经为我们完成了。 如果你检出master分支并编译它,它就会有新开发的功能。 Git实际执行的是三向合并。 它比较master和dev-branch分支中的最新提交,以及master分支中紧接在dev-branch创建之前的提交。 然后它在master分支上执行提交。
合并被认为是非破坏性的,因为它们不会删除任何内容,也不会更改任何 Git 历史记录。 dev-branch仍然存在,之前的提交都没有改变。 创建一个新的提交来捕获三向合并的结果。
合并后,我们的 Git 存储库看起来像一个时间线,其中有一条备用线分支,然后返回到主时间线。

dev-branch分支已经并入master分支。
如果您在一个项目中有很多分支,项目的历史就会变得混乱。 如果一个项目有很多贡献者,通常就是这种情况。 因为开发工作分成许多不同的路径,所以开发历史是非线性的。 如果分支有自己的分支,理清提交历史变得更加困难。
请注意,如果您在master分支中有未提交的更改,则需要先对这些更改执行一些操作,然后才能将任何内容合并到其中。 您可以创建一个新分支并在那里提交更改,然后进行合并。 然后,您需要将临时分支合并回主分支。
这行得通,但 Git 有一个命令可以实现同样的事情,而无需创建新的分支。 stash命令为您存储未提交的更改,并允许您使用stash pop回调它们。
你会像这样使用它们:
藏 git 合并开发分支 藏流行音乐
最终结果是一个合并的分支,其中恢复了未保存的更改。
什么是 Git 变基?
Git rebase命令以完全不同的方式实现了它的目标。 它从你要变基的分支中获取所有提交,并将它们重播到你要变基的分支的末尾。
以我们之前的例子为例,在我们执行任何操作之前,我们的 Git 存储库看起来像这样。 我们有一个名为dev-branch ,我们想将这些更改移动到master分支。

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


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 合并新功能

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

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

Git Rebase 与 Merge:您应该使用哪一个?
这不是rebase与merge的情况。 它们都是功能强大的命令,您可能会同时使用它们。 也就是说,在某些用例中, rebase并不能很好地工作。 使用merge的错误导致的取消选择错误令人不快,但是rebase导致的取消选择错误是地狱般的。
如果您是唯一使用存储库的开发人员,那么您使用rebase做一些灾难性的事情的可能性就会降低。 例如,您仍然可以在错误的方向上rebase基,并将您的 master 分支rebase到您的new-feature分支上。 要恢复您的master分支,您需要再次rebase ,这次是从您的new-feature分支到您的master分支。 这将恢复您的master分支,尽管历史看起来很奇怪。
不要在其他人可能工作的共享分支上使用rebase 。 当您将重新设置基础的代码推送到远程存储库时,您对存储库的更改会给很多人带来问题。
如果你的项目有多个贡献者,安全的做法是只在你的本地存储库上使用rebase ,而不是在公共分支上。 同样,如果拉取请求构成代码审查的一部分,请不要使用rebase 。 或者至少,在创建拉取请求后不要使用rebase 。 其他开发人员可能正在查看您的提交,这意味着这些更改位于公共分支上,即使它们不在master分支上也是如此。
危险在于您要对已经推送到远程存储库的提交进行rebase ,而其他开发人员可能已经基于这些提交进行了工作。 您的本地rebase将使那些现有的提交消失。 如果您将这些更改推送到存储库,您将不会受到欢迎。
其他贡献者将不得不通过混乱的merge才能将他们的工作推回存储库。 如果您随后将他们的更改拉回到您的本地存储库,您将面临取消挑选一堆重复更改的麻烦。
变基,还是不变基?
在你的项目中, Rebase可能是非法的。 可能存在当地的文化异议。 一些项目或组织将rebase视为异端和亵渎行为的一种形式。 有些人认为 Git 历史应该是不可侵犯的、永久的记录所发生的事情。 因此, rebase可能不在讨论之列。
但是,在本地使用,在私有分支上, rebase是一个有用的工具。
在你 rebase之后推送,并将它限制在你是唯一开发人员的分支上。 或者至少,所有开发都已停止,并且没有其他人基于您分支机构的提交开展任何其他工作。
这样做,您将避免任何问题。
相关:如何检查和更新你的 Git 版本



