Git Rebase 和黄金法则解释
这篇文章是这篇文章的后续,我们探讨了 .git 目录。
重新定位的基础
当你思考 git 中的 rebase 是什么时,你可能会想到这一点:
你可以说,当你进行变基操作时,你“拔掉”了想要变基的分支,然后“重新插上”另一个分支的顶端。这与事实相差不远,但值得深入挖掘一下。如果你查看文档,关于变基操作是这样写的:
“git-rebase:将本地提交转发到更新后的上游头部”— git doc
这没什么帮助,不是吗?大概翻译如下:
git-rebase:将您分支上的所有提交重新应用到另一个分支的末端。
这里最重要的词是“重新应用”,因为 rebase 不仅仅是按 ctrl-x/ctrl-v 从一个分支切换到另一个分支。rebase 会按顺序从当前分支获取所有提交,并将它们重新应用到目标分支。此行为主要有两点含义:
-
通过重新应用提交,git 会创建新的提交。即使这些新的提交包含相同的更改,git 也会将其视为完全不同且独立的提交。
-
Git rebase 会重新应用提交,并且不会销毁旧提交。这意味着即使在 rebase 之后,你的旧提交仍然会保留在 .git 目录下的 /objects 文件夹中。如果你不太了解 git 如何处理和存储提交,可以在这里学习一些有趣的知识。
因此,这可以更准确地表示变基期间实际发生的情况:
如您所见,功能分支有全新的提交。如前所述,相同的一组更改,但从 git 的角度来看是完全不同的对象。您还可以看到,先前的提交并没有被销毁。它们只是无法直接访问。如果您还记得,分支只是指向提交的指针。因此,如果分支和标签都没有指向提交,则几乎不可能访问,但提交仍然存在。
现在让我们来谈谈这个著名的黄金法则。
rebase 的黄金法则
“任何人都不应该对共享分支进行 rebase” — 关于 rebase 的所有人
你可能遇到过这条规则,只是表述方式不同。如果你没遇到过,这条规则其实很简单。永远、永远、永远不要对共享分支进行 rebase。我所说的共享分支是指存在于远程仓库中,并且团队中其他人可以 pull 的分支。
这条规则常常被当作神圣的真理,我认为如果你想加深对 git 的理解,理解它可能是一件好事。
为了做到这一点,让我们想象一下开发人员违反规则的情况,看看会发生什么。
假设 Bob 和 Anna 都在开发同一个项目。以下是 Bob 和 Anna 在 GitHub 上的仓库和远程仓库的概览:
现在,Bob 无意中打破了 rebase 的黄金法则,与此同时 Anna 决定继续开发该功能并创建了一个新的提交:
鲍勃现在尝试推动,但他被拒绝了,并收到这样的消息:
Oh My Zsh带有 agnoster 主题,适合那些关心的人
这里 git 不太高兴,因为它不知道如何将 Bob 的功能分支与 GitHub 的功能分支合并。通常,当你将分支推送到远程仓库时,git 会将你尝试推送的分支与远程仓库当前的分支合并。实际上,git 会尝试快进你的分支,我们将在以后的文章中详细讨论这一点。你需要记住的是,远程仓库无法以简单的方式处理 Bob 尝试推送的变基分支。
Bob 的一个解决方案是执行 git push — force,基本上就是告诉远程仓库:
“不要尝试合并或在我推送的内容和你已有的内容之间做任何工作。删除你之前版本的功能分支,我推送的内容现在是新的功能分支。”
最终结果如下:
现在安娜想要推动她的改变:
这很正常,git 只是告诉 Anna 她没有该功能分支的同步版本,也就是说,她所在的分支版本和 GitHub 上的版本不同。所以 Anna 很自然地会进行拉取操作。就像你推送代码时 git 会尝试将你本地的分支与远程仓库中的内容合并一样,你拉取代码时 git 也会尝试将远程仓库中的内容与你本地的分支合并。
在拉取之前,这些是远程和本地功能分支中的提交:
A--B--C--D' origin/feature // GitHub
A--B--D--E feature // Anna
当你pull的时候,git必须进行合并来解决这个问题。具体过程如下:
提交 M 代表合并提交。Anna 和 GitHub 的功能分支终于在这个提交中重新合并了。Anna 终于松了一口气,她成功解决了所有合并冲突,现在可以推送她的工作了。Bob 决定拉取,现在每个人都同步了。
看看这些乱七八糟的东西,就足以让你相信黄金法则的有效性。你必须记住,你面前的乱七八糟的东西只有一个人造成,而且只在两个人共享的分支上。想象一下,一个10人的团队在做同样的事情。人们使用git的众多原因之一就是为了能够轻松地回溯到过去,而你的历史记录越乱,它就越复杂。
你还会注意到远程分支上存在重复的提交,D 和 D' 包含相同的更改。基本上,重复提交的数量可能与你重新定基的分支中的提交数量一样多。
如果你仍然不相信,不妨想象一下第三个开发者 Emma 的情形。在 Bob 把一切都搞砸之前,她一直在功能分支上工作,现在想要推送。注意,她是在我们之前的小场景之后推送的。
更新:正如一些 Reddit 用户提到的,这篇文章可能会让你认为 rebase 只能用于将一个分支 rebase 到另一个分支之上。事实并非如此,你可以在同一个分支上 rebase,但这是另一回事。
感谢您阅读:
我希望您阅读这篇文章后能学到一些有价值的东西,并使您能够更轻松地使用 git。
您可以在此处阅读第 3 部分。
如果你喜欢 JS,我刚刚发布了一些你可能会喜欢的东西:
请在评论中告诉我您最近对 Git 的困惑,不要害羞 🙂 并且,如果您喜欢这篇文章,请不要忘记订阅我的时事通讯,您还将免费获得我的下一本关于 git 的电子书的第一章(即将推出)。
鏂囩珷鏉ユ簮锛�https://dev.to/daolf/git-rebase-and-the-golden-rule-explained-13h6