常规的git rebase,在您自己的计算机上本地完成的,会尽力优化一些东西。GitHub rebase 在 GitHub 的计算机上远程完成,努力确保没有任何内容得到优化。
我认为,一个具体的例子在这里很有帮助。假设我们在本地有这些提交:
\n I--J--K <-- feature (HEAD)\n /\n...--F--G--H <-- main\nRun Code Online (Sandbox Code Playgroud)\n如果像这样运行git rebase main, while on feature,您的 Git必须将提交复制I到新的提交I\'。I原始提交和新提交之间的区别I\'在于,它I\'可能包含不同的快照(所有文件的集合),并且I\' 肯定有不同的父级。的父提交I\'是H(vs Gfor I)。H如果中的快照与 中的快照不同,则快照是不同的G,因为变基的目的是将G-vs-I 更改转换为-vs-中的相同更改:HI\'
I--J--K [abandoned]\n /\n...--F--G--H <-- main\n \\\n I\'-J\'-K\' <-- feature (HEAD)\nRun Code Online (Sandbox Code Playgroud)\n类似的规则适用于J\'-vs-J和K\'-vs- K。新的和改进的提交是不同的;它们必须是不同的。
但是,如果你有这个:
\n I--J--K <-- feature (HEAD)\n /\n...--F--G--H <-- main\nRun Code Online (Sandbox Code Playgroud)\n当你运行 时git rebase main,你的 Git 可以查看H和的相对位置,I并对自己说:嘿...如果我复制I到一个新的I\',其父级是H,结果将匹配I。H我从到得到的差异以及我从新副本I得到的差异将是相同的。父母也是一样的。那么……为什么要费心去复制呢?让我重新使用现有的.HI\'I
你的 Git 也会对J和重复这个推理K。因此,当变基完成后,您的存储库中将包含以下内容:
I--J--K <-- feature (HEAD)\n /\n...--F--G--H <-- main\nRun Code Online (Sandbox Code Playgroud)\n从字面上看,什么都没有改变。3次提交的实际hash ID是相同的;提交者是相同的;一切都是逐位相同的,并且提交哈希 ID 仍然匹配。
\n但是,您可以强制Git复制提交,并放入新的提交者时间戳。如果你强迫你的 Git 这样做,你最终会得到:
\n I--J--K [abandoned]\n /\n...--F--G--H <-- main\n \\\n I\'-J\'-K\' <-- feature (HEAD)\nRun Code Online (Sandbox Code Playgroud)\n其中三个新提交具有相同的快照,但提交者行中的时间戳不同,因此与原始三个提交的哈希 ID 不同。
\n要像这样强制进行本地变基,您可以使用git rebase -f; 无论有或没有,这都有效-i。但是,如果您在这里不使用-f或--force选项,那么您的 Git 何时以及是否真正设法在本地进行此优化取决于您的特定 Git 版本。所以并不是每个变基都得到这样的优化。但它很常见,并且出于某些特定目的,1强制新提交选项已经存在了相当长的时间。
当您使用 GitHub rebase-and-merge 选项时,GitHub 实际上会打开强制选项。无论是字面上的情况,还是只是 GitHub 实现 rebase 代码方式的副作用\xe2\x80\x94,他们必须稍微修改 Git,以使他们的一些特殊的分叉共享魔法更好地工作,例如,这可能在这里发挥作用;他们使用裸存储库,无论如何,rebase 通常是不可能的\xe2\x80\x94我不知道。但他们最终每次都会进行复制。这会committer在每次提交中产生新信息,这意味着新提交具有与原始信息不匹配的新的、唯一的哈希 ID。
(在企业环境中工作时,这实际上相当烦人。至少,我发现是这样。即使不使用分叉也会发生这种情况,所以裸回购可能是真正的罪魁祸首。)
\n1强制复制变基的主要用途,至少据我所知,是重新进行已恢复的合并。假设我们有这个:
\n I--J--K <-- feature\n / \\\n...--F--G--H------L--M--W <-- main\nRun Code Online (Sandbox Code Playgroud)\nfeature被合并到哪里,main但后来有人发现有一个错误,所以M使用 commit 恢复了提交W(M 颠倒,从 Linus 窃取)。然后修复了该错误:
I--J--K--N <-- feature\n / \\\n...--F--G--H------L--M--W <-- main\nRun Code Online (Sandbox Code Playgroud)\n但是如果我们现在feature按main原样合并,我们将遇到合并冲突和/或不会从提交中获得任何效果I-J-K,因为恢复W会撤消它们所做的事情。发生这种情况是因为 Git 使用哈希 ID 来了解发生了什么。
那么,假设我们欺骗Git 进行就地复制 I-J-K,即使它是“不必要的”:
I--J--K\n / \\\n...--F--G--H------L--M--W <-- main\n \\\n I\'--J\'--K\'--N <-- feature (HEAD)\nRun Code Online (Sandbox Code Playgroud)\n我们现在可以git switch main && git merge feature:
I--J--K\n / \\\n...--F--G--H------L--M--W--M2 <-- main (HEAD)\n \\ /\n I\'--J\'--K\'--N <-- feature\nRun Code Online (Sandbox Code Playgroud)\n其中M2有一个基本上是M-plus-the-bug-fix-in- 的快照N。
当然还有其他方法可以得到想要的结果,但这是Linus 多年前概述的方法。
\n| 归档时间: |
|
| 查看次数: |
357 次 |
| 最近记录: |