压缩和删除git中的提交有什么区别?

时间:2017-05-31 15:56:23

标签: git github git-rebase git-squash

假设我

git rebase -i HEAD~3

并在文本编辑器中打开以下内容:

pick ae27841 Commit 1 
pick fd8a71e Commit 2
pick badd490 Commit 3

我想将这3个提交转换为1个提交,因此我可以将该提交推送到我的存储库,然后调用pull请求。我知道有两种方法可以解决这个问题:

  1. 我可以将一个提交保留为pick并压缩另外两个提交。即

    pick ae27841 Commit 1 
    s fd8a71e Commit 2
    s badd490 Commit 3
    
  2. 我可以删除这3次提交中的2次。即。

    pick ae27841 Commit 1 
    
  3. 这两个命令有什么区别?据我了解,每次提交都是项目的不同版本。因此我的最新提交将是我的最新版本吗?所以我最近的提交就是我需要保留的一切。由于其他2个提交是项目的“旧”版本,我不需要它们,所以我可以删除它们。方法2是否正确的方法将我的3个提交转换为一个?     如果是这样,我需要什么样的情况来压缩我的提交呢?

    这里的正确方法是什么?压缩或删除提交?

4 个答案:

答案 0 :(得分:1)

删除提交时,将删除它从历史记录中引入的所有更改,即从其后的所有提交中删除。 Squashing也会从历史记录中删除提交,但其更改将合并到生成的提交中。

答案 1 :(得分:0)

更新 - 从评论中看,误会似乎与问题有点不同,所以我在底部添加了一些注释

原始答案

压缩提交是将其更改添加到之前的提交中。删除提交是为了不执行更改。

所以,如果你有

A --- B --- C <--(master)

其中A创建A.txtB创建B.txtC创建C.txt,如果你压缩你提交的提交

ABC <--(master)

其中ABC是一个创建A.txtB.txtC.txt的提交,而如果您删除了BC

A <--(master)

并且只创建了A.txt

添加了备注

因此,git COMMIT对象除了其他内容外,还有一个对TREE对象的引用,表示当时的项目内容。 TREE大致是一个目录列表,包含其他TREE对象(子目录)和BLOB对象(文件)的名称列表。

在内部(如果对象被打包),BLOB可能表示为来自另一个BLOB的增量 - 但当前版本通常是完整对象,其中delta用于构建旧版本的文件。

在任何一种情况下,在任何有效的仓库中,您可以重建项目的完整状态,因为它是从TREE上的COMMIT参考提交的; PARENT用于历史记录跟踪,但不需要构建项目状态。

然而,当您在rebase期间pick提交时,这并不意味着您正在复制该提交TREE ;相反,它意味着git将找出该提交的TREE和该提交PARENT的{​​{1}}之间的差异,并应用该组变化。

TREEREBASE操作期间,根据与父项的差异处理提交的这一想法非常重要。在某种程度上,即使提交是结构化的,它可以重现项目的快照,但通常认为它只是代表那组更改。

答案 2 :(得分:0)

在Git中,压缩和删除在技术上是相同的。他们创建新的提交,将一些现有的提交作为父级,并且不删除任何提交。

假设提交历史记录是ABCD。当压缩BCD时,创建新的提交E作为A的新子节点。新提交包括BCD的更改。 BCD仍在那里。然后,当前ref(例如,分支或HEAD)从A移动到E(压缩合并)或从D移动到E(交互式rebase)。如果裁判在D处并且现在在E处,那么BCD似乎已经丢失但实际上他们仍然存在。

至于&#34;删除&#34;通过樱桃挑选C到A,一个新的提交C&#39;是作为A. C&#39;的新孩子而创建的。具有C的等效变化(并不总是与C完全相同)。 BCD仍在那里。当前的ref将A移动到C&#39;。当您运行git reset时,当前引用从一次提交移动到另一次提交。

另一个例子是git commit --amend。当你为ABCD运行它时,新的提交D&#39;被创造为C的新生儿。 ref从D移动到D&#39;。现在D似乎被删除但它仍然存在。据说Amend修改并更新了最后一次提交,但实际上它创建了一个新的兄弟提交。

答案 3 :(得分:0)

首先,关于git的这个概念在这里是错误的:

  

据我了解,每次提交都是项目的不同版本。   因此,我的最新提交将是我的最新版本吗?

删除提交2和提交3时,提交1将更改。让我称之为(承诺1)&#39;。即使(承诺1)&#39;使用Commit 1保持相同的提交消息,与先前版本相比保持相同的修改,它们不是相同的版本。 (承诺1)&#39;和Commit 1有不同的版本哈希。

方法1:这就是你想要的。保留最后一个版本的代码,保留最后一次提交消息。但是你应该注意HASH已经改变了。

方法2:不是你想要的。提交2和提交3中提交的代码将丢失。