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

Nir*_*bag 6 git github git-rebase git-squash

假设我这样做

git rebase -i HEAD~3

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

pick ae27841 Commit 1 
pick fd8a71e Commit 2
pick badd490 Commit 3
Run Code Online (Sandbox Code Playgroud)

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

  1. 我可以保留一个提交pick并压缩其他两个。IE

    pick ae27841 Commit 1 
    s fd8a71e Commit 2
    s badd490 Commit 3
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我可以删除这 3 个提交中的 2 个。IE

    pick ae27841 Commit 1 
    
    Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*ger 5

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


原答案

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

所以如果你有

A --- B --- C <--(master)
Run Code Online (Sandbox Code Playgroud)

如果你压缩你得到的提交,那么在哪里A创建A.txtB创建B.txtC创建C.txt

ABC <--(master)
Run Code Online (Sandbox Code Playgroud)

其中是创建, ,ABC的单个提交,而如果您删除并得到A.txtB.txtC.txtBC

A <--(master)
Run Code Online (Sandbox Code Playgroud)

并且只会A.txt被创建。


添加注释

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

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

无论哪种情况,在任何有效的存储库中,您都可以重建项目的完整状态,因为它是从TREE; 上的引用提交的COMMIT。用于PARENT历史跟踪,但构建项目状态不需要。

然而,当您pick在变基期间提交时,这并不意味着您正在复制该提交TREE;相反,这意味着 git 将找出该提交和该提交之间的差异,TREE并应用这组更改。PARENTTREE

根据提交与父提交的差异来处理提交的想法在REBASEMERGE操作期间都很重要。在某种程度上,即使提交是结构化的,因此它可以重现项目的快照,但将其视为仅代表那组更改通常很有用。


cho*_*oba 0

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