你的问题存在的理由:你有
A - B - C - D - E
但你想要
A - E
美好的。让我们首先澄清您问题中的一些误解。
提交是不可变的
提交不仅仅是快照。他们也是不可变的。与 E 有任何不同的提交都不会是 E。它可能具有相同的内容提交消息为 E,但如果它与 E 完全不同,那么它就是不同的 commit.
亲子关系是提交的一部分
好吧,我刚刚说过了,但我会再说一遍。提交不仅仅是它们的内容。它们还包含许多其他内容,特别是有关其父母是谁的信息。
好的。现在,在您的图表中,D 是 E 的父级。没有 D 作为其父级的提交将具有不同的父级。我们刚刚说过,提交是不可变的。因此,如果我们想象 E 以 A 作为其父代,那不会是E。再说一次,我们可能call它以一种非正式的方式“E”;它可能具有与 E 相同的提交消息;但这将是一个不同的 commit.
无需剪切和粘贴
以上足以解释为什么你不能仅仅“剪切”B、C和D,然后“粘贴”E来追随A。你不能将E“粘贴”到任何地方!只有一个 E — 不仅在您的存储库中,而且在整个宇宙中 — 并且 D 是它的父级,这就是结束。
因此,为了从可见历史中消除 B、C 和 D,我们必须以某种方式rewriteE 制作一个不同的提交,以 A 作为其父级。这就是为什么需要重新设置基准(或类似的东西)才能生成您想要的历史记录的基本原因。历史
A - E
是不可能的。你能拥有的是
A - E'
其中第二个提交的名称为“e-prime”,在您的脑海中与 E 有一些相似之处,但它是notE. 你需要一种连贯的方式来做到这一点。这就是为什么你必须这样做some一种改变历史的舞蹈。
但这种舞蹈不需要重新定位——正如我们现在将看到的那样。喝一口咖啡,我们继续吧。
无需变基
现在假设你的问题的意思是这样的:B、C 和 D 是通往黄金真理的步骤,但 E 包含黄金真理,我真的不需要向我的人“展示我的工作”。同事和世界。因此,我想隐藏中间步骤,只是从 A 到 E(抱歉,到 E'),作为对所发生事件的纯粹而简单的陈述。
那么你实际上不需要变基。说啊
git reset --soft <SHA of A>
git commit -m 'message identical to the E message'
这将导致您想要的结果
A - E'
我们刚刚做了什么?我们从您自己陈述的事实开始:提交包含快照。当我们说reset --soft
,我们基本上将该快照的内容生成到工作树和索引中。那么,当我们进行新的提交时,该提交就是项目的快照,其状态与 E 所描述的状态完全相同。但是当我们进行这个新提交时,HEAD 是 A。所以这个新提交的父级是 A!问题解决了。
所以是的,我们could已经重新设置并压缩了中间提交以获得相同的结果。但这对于那些不知道如何或不愿意打扰的人来说只是一种方便的方式来更直接地完成同样的事情。 Git 交互式 rebase 是某些常见类型历史转换的智能且方便的简写;但它没有做任何你自己以其他方式做不到的事情。
无需变基,ever
我只是想让你记住,你永远不需要变基。它所做的一切都可以通过一系列有时乏味且复杂的步骤来完成,这些步骤更加基本和直接,并且(可能)不方便。
例如,假设您想消除 B 和 C,但保留 D 和 E(实际上是 D' 和 E',正如我们所知 - D 将被 D' 替换,因为新提交的父级是 A,而不是 C,并且E 将被 E' 替换,因为新提交的父级是 D',而不是 D)。
您无需交互式变基即可完成此操作。在 D 处启动一个新分支。将该分支软重置回 A 并使用 D 的提交消息进行提交,就像我们之前所做的那样。现在,将 E 挑选到这个新分支的末尾,并给出结果提交 E 的旧消息。现在清理分支情况,就完成了。
我并不是说这比交互式变基更容易;而是说这比交互式变基更容易。显然不是。但这不是重点。关键是交互式 rebase 只是一个拐杖。一个非常棒的拐杖!但这不是魔法。
掉落不是南瓜
最后,你在问题中说了一些非常错误的话:你说“丢弃或挤压”。这里没有“或”:它们是完全不同的东西!压缩保留了一系列压缩中最后一次提交的内容。掉落则不然!如果您删除了 B、C 和 D,则生成的 E' 将包含看起来像的快照什么都没有就像现在的E!
例如,假设 B 包含一个新文件myfileA 没有。假设 C、D 和 E 也都有该文件。然后删除 B 将得到 E'lacks文件myfile.
这是因为,虽然提交不是差异,但差异do exist(在 Git 的心中,没有写入历史)并且他们are used在合并的过程中。变基实际上是一种合并形式(我现在不想讨论这个问题)。因此,通过删除 B,您将反转从 A 到 B 的差异。并且由于该差异的一部分是创建myfile,反转 diff 是一种说法not创造myfile。所以myfile当 rebase 结束时,不会出现在 E' 中,即使它did出现在E中。
压扁什么
最后但并非最不重要的一点是:您问题中的这句话也是错误的:“squash
提交 B、C 和 D”。不。要通过交互式变基获得您想要的结果,您需要压缩 C、D 和 E。换句话说,选择列表最初看起来像这样:
pick f343cc4 B
pick f750aa9 C
pick 0105b79 D
pick 46fe327 E
你可以将其编辑为如下所示:
pick f343cc4 B
squash f750aa9 C
squash 0105b79 D
squash 46fe327 E
然后,您可以选择 E 的提交消息作为生成的新提交的提交消息。