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 版本