压缩git中的提交意味着什么?


116

在git中提交Squashing是什么意思。如何在Github中压缩提交?

我是Git的新手,我要求分配给Coala-analyzer中的新手错误。我修复了该错误,现在我被要求压缩提交内容。我该怎么做?


嘿@Lakshman随时接受投票最高的答案。它可以正确回答您的问题。
Mostafiz Rahman

Answers:


179

您可以将Git视为工作目录快照的高级数据库。

Git的一个非常不错的功能是能够重写提交的历史记录。
这样做的主要原因是,许多这样的历史记录仅与生成它的开发人员相关,因此在将其提交到共享存储库之前,必须对其进行简化或使其更加美观。

从惯用的观点来看,压榨一次提交意味着将所述提交中引入的更改移到其父级中,以便最终得到一个提交而不是两个(或更多)提交。
如果多次重复此过程,则可以将n次提交减少为一个。

在视觉上,如果你在提交标记开始你的工作开始,你要想这

Git压扁

您可能会注意到,新的提交具有略深的蓝色阴影。这是故意的。

在Git中,挤压是通过Rebase来实现的,Rebase是一种特殊形式的称为Interactive Rebase
简化了将一组提交重新建立到分支B的时间时,您可以应用这些提交所引起的所有更改,这些更改从B开始而不是其原始祖先开始。

视觉线索

在此处输入图片说明

再次注意不同的蓝色阴影。

交互式变基让您选择应如何重新确定提交。如果运行此命令:

 git rebase -i branch

您最终将得到一个文件,其中列出了将被重新基准化的提交

 pick ae3...
 pick ef6...
 pick 1e0...
 pick 341...

我没有名字的提交,但这些四个一意在将提交从开始

关于此列表的好处是它是可编辑的
您可以忽略提交,也可以压缩它们
您所要做的就是将第一个单词更改为南瓜

 pick ae3...
 squash ef6...
 squash 1e0...
 squash 341...

如果关闭编辑器,但未发现合并冲突,则将得到以下历史记录:

在此处输入图片说明

在您的情况下,您不想基于其他分支,而希望基于先前的提交。
为了转换历史记录,如第一个示例所示,您必须运行类似

git rebase -i HEAD~4

更改“命令”以压缩除第一个提交以外的所有提交,然后关闭编辑器。


关于更改历史记录的注意事项

在Git中,永远不会编辑提交。可以将它们修剪,设置为不可访问,克隆但不能更改。
重新确定基准时,实际上是在创建新的提交。
旧的不再可以通过任何引用访问,因此历史记录中没有显示,但它们仍然存在!

这是您实际上获得的变基:

在此处输入图片说明

如果您已经将它们推到某个位置,则重写历史记录实际上将创建一个分支!


很好-尽管原始提交注释会发生什么-将它们合并为一个大的提交注释还是丢失?
Paul R

来自man git rebase折叠提交的建议提交消息是第一次提交以及使用“ squash”命令的提交消息的串联
Margaret Bloom 2016年

1
这是我见过的最好的解释,谢谢。
凯里·琼斯

关于第一个图像中的压榨:您能否举一个例子,说明HEAD在压榨之前(浅蓝色)和之后(深蓝色)具有不同的工作目录?在所有示例中,我尝试压扁看起来只是删除了START和HEAD之间的三个提交。
Actual_panda

@actual_panda我不确定我是否遵循。HEAD是对提交的引用。提交商店增量。工作目录是整个存储库的一个属性,它取决于您检出的提交。通常,签出时,两个引用(例如HEAD和START)始终提供两个不同的工作目录。如果将南瓜重新放置在同一分支上,则效果是“松开”了中间提交,但实际上,git用所有增量制作了一个新的。git diff可能会帮助您显示发生了什么。
玛格丽特·布鲁姆

22

rebase命令在其--interactive(或-i)模式下有一些很棒的选项,使用最广泛的选项之一是压缩提交。这样做是将较小的提交合并到较大的提交中,如果您要完成当天的工作或者只是想以不同的方式打包更改,这将很有用。我们将介绍如何轻松实现此目的。

请注意:仅对尚未推送到外部存储库的提交执行此操作。如果其他人基于要删除的提交进行工作,则可能会发生许多冲突。如果您的历史记录已与其他人共享,则不要重写。

因此,假设您刚刚进行了一些小的提交,而您想从中进行一次更大的提交。当前我们存储库的历史记录如下:

在此处输入图片说明

如果将最后4个提交打包在一起,那么它们会更快乐,所以让我们通过交互式重新基准化来做到这一点:

$ git rebase -i HEAD~4

pick 01d1124 Adding license
pick 6340aaa Moving license into its own file
pick ebfd367 Jekyll has become self-aware.
pick 30e0ccb Changed the tagline in the binary, too.

# Rebase 60709da..30e0ccb onto 60709da
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

因此,这里发生了一些事情。首先,我告诉Git,我想使用HEAD〜4所在的HEAD中的最后四次提交来重新确定基准。Git现在将我带到上面的文本编辑器中,并对可以完成的操作进行了一些解释。您可以从此屏幕上找到许多选项,但是现在我们只是将所有内容压缩为一次提交。因此,将文件的前四行更改为此将达到目的:

pick 01d1124 Adding license
squash 6340aaa Moving license into its own file
squash ebfd367 Jekyll has become self-aware.
squash 30e0ccb Changed the tagline in the binary, too.

基本上,这告诉Git将所有四个提交合并到列表中的第一个提交中。完成并保存后,将弹出另一个编辑器,并显示以下内容:

# This is a combination of 4 commits.
# The first commit's message is:
Adding license

# This is the 2nd commit message:

Moving license into its own file

# This is the 3rd commit message:

Jekyll has become self-aware.

# This is the 4th commit message:

Changed the tagline in the binary, too.

    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    # Explicit paths specified without -i nor -o; assuming --only paths...
    # Not currently on any branch.
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #   new file:   LICENSE
    #   modified:   README.textile
    #   modified:   Rakefile
    #   modified:   bin/jekyll
    #

由于我们合并了这么多提交,因此Git允许您根据流程中涉及的其余提交来修改新提交的消息。根据需要编辑消息,然后保存并退出。完成后,您的提交已被成功压缩!

Created commit 0fc4eea: Creating license file, and making jekyll self-aware.
 4 files changed, 27 insertions(+), 30 deletions(-)
  create mode 100644 LICENSE
    Successfully rebased and updated refs/heads/master.

如果我们再次回顾历史…… 在此处输入图片说明

因此,到目前为止,这还算比较轻松。如果您在调整基准期间遇到冲突,通常通常很容易解决这些冲突,Git会尽可能地引导您解决冲突。这样做的基础是修复有问题git add的文件冲突,然后git rebase --continue将其恢复。当然,git rebase --abort如果需要,执行a 将使您回到以前的状态。如果由于某种原因您丢失了rebase中的提交,则可以使用reflog将其取回。

可以在此链接中找到详细信息。


3
谢谢!如果有人对VIM感到不满意,...当您输入要进行编辑的操作时,请按“ i”进入编辑模式。完成更改后,请按Escape键,然后输入“:wq”,它将使您前进。(Mac)
Farasi78年

对于执行此操作时的注意事项和上下文,请+1。以我的个人经验,如果您一个人在功能分支上工作,并进行大量琐碎的提交,例如“更新的自述文件”,“没有人关心的事情”,并且准备合并分支,那么可能会很好,好吧,将这些全部压缩为一次提交。没有人会想要恢复到您的“没有人关心的事情”,并且污染了提交历史
Adam Hughes

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.