Git rebase 很容易成为 Git 中最容易被误解的命令之一。 初学者经常会以错误的方式使用此命令弄乱他们的工作树,或者找不到 git rebase 和 merge 之间的区别。 因此,在本文中,我们尝试使用图形表示来详细解释 git-rebase 中实际发生和未发生的情况。 这篇文章是关于 rebase 的讨论,而不是关于如何 rebase 的简单教程。
Git 存储命令
什么是变基?
从字面上看,rebase 意味着更改对象的基础。 Git rebase 对 git branch 做同样的事情——它改变了分支的基础。
但是分支的基础到底是什么,我们为什么要这样做? 我们将在本文接下来的几节中回答这些问题。
分支的基础是什么?
分支的基础是从它的父分支分支出来的提交。 它也可以定义为与分支及其父分支相同的最新提交。 这是一个简单的可视化来理解它。
功能 1 是功能分支偏离主分支的提交。 所以它是功能分支的基础提交。
在 git rebase 中,我们有兴趣将此基础更改为另一个提交,这意味着功能 2 提交将不再指向功能 1,而是其他一些提交。
git rebase 有什么作用?
在我们深入了解命令的细节之前,先快速浏览一下 git 命令的语法:
git rebase <target branch>
此命令将当前分支重新绑定到目标分支上。 这意味着当前分支现在基于目标分支上的最后一次提交。 因此,git commit-graph 看起来就像分支从未与原始分支分离,并且提交基于当前基础。 这使提交图具有线性外观的提交图。
命令语法不是最重要的部分,重要的部分是命令的功能。 如果你搞砸了 git rebase,你会得到一些不需要的提交和复杂的提交图,而不是你想要的线性干净的提交图。 因此,让我们更详细地了解 git rebase。
正如我们在文章开头所讨论的那样,Git rebase 更改了分支的基础。 但这条线只是部分正确。
这些是我们可能期望 git rebase 做的事情
- 将分支的基础更改为目标分支上的最新提交。
- 保持我当前分支中的提交不变。
如果 git rebase 遵循此原则,则命令后图 1 中的 git commit 图 git rebase master
应该看起来像:
但是我们在这里遗漏了一个小问题:
- 遵循上述方法基本上会破坏对该分支进行的提交的提交历史记录。 任何删除或重写 git 历史记录的命令都可能是导致问题的潜在原因。
- 如果功能分支上的提交日期早于目标分支上的较新提交,则重新定位的分支将具有比它所基于的提交更旧(相对于时间)的较新提交,从而产生绝对的悖论。
为了避免这些问题, git rebase 实际做的是:
- 将分支头指针重定位到目标分支指针。 (功能现在指向主人)
- 在分支上进行新的重复提交。 这些提交本质上与原始提交具有相同的代码更改,但具有不同的 SHA1 值。
- 较旧的提交仍以分离状态出现在图上。
因此,让我们最终想象一下实际 git-rebase 中会发生什么,
我什么时候使用 git rebase?
与 git merge 创建的凌乱图不同,Git rebase 仅用于具有干净的线性提交图。 所以这是这两者之间的权衡
- Git merge 允许保留提交历史,但额外提交和复杂提交图的成本
- Git rebase 保持提交次数不变,但代价是抽象掉提交历史。
因此,您可以合并的每个分支都可能重新定位,反之亦然,但建议不要重新定位公共/共享分支。 在使用 rebase 时,用户必须牢记保留历史记录和干净提交图之间的权衡。
结论
这使我们到了关于 git-rebase 的文章的结尾。 可视化 git 用于 git 命令的图形表示。 请继续关注有关 git 和其他开源程序的更多此类文章。