如何在Git中压缩提交?

我试图压缩我的提交并将我的分支合并为一个单独提交。 这是我正在尝试的。 我切换到主分支,然后我做

git merge --squash <branch_name>

我明白了

Automatic merge went well; stopped before committing as requested
Squash commit -- not updating HEAD

之后我承诺。 但是,这是我得到的

$ git commit -m "Resolved"
On branch master
nothing to commit, working tree clean

出于某种原因,这些更改没有反映出来,我得到的信息没有提交。 我已经在堆栈上看过很多帖子和问题,但到现在为止没有任何帮助。


我不完全清楚你是什么提交你压缩合并,因此你为什么得到这个结果。 你可以自己清除第一个问题(这对我来说没有太大帮助,因为我没有提交):

git log --decorate --oneline --graph --boundary master...<branch-name>

(注意这里的三个点)。 这将显示你现在在master提交了什么,以及你将通过这两个分支的merge base commit从<branch-name>引入什么提交。

然而,在任何情况下,我都可以做出一个很好的猜测,因为git merge工作的方式是将此合并基础与两个分支提示进行比较。 下面是一个合并前的示例图片段(在这一点上,这是一个常规合并还是一个壁球合并并不重要):

...--B--C--D   <-- master (HEAD)
      
       E--F--G   <-- feature

每个大写字母代表一个提交(其真实ID是一个Git哈希ID,如a9f3c72或其他)。 合并这里碱提交是提交B :它是其中提交的链,从两种起始masterfeature在同一时间和向后工作(向左在该曲线图中)中,首先汇集一起。 换句话说,提交B是分支master分支和分支feature上的最新提交。 这就是合并基础提交的原因。

实际上,Git将运行:

git diff B D   # see what "we" did on branch master
git diff B G   # see what "they" did on branch feature

然后Git必须结合这些变化:如果我们改变README在最后添加一行,Git应该把这个额外的行添加到最后。 如果他们以某种方式更改了foo.py (可能添加了一行并删除了另一行),Git应该将其更改为foo.py 如果我们都做了完全相同的事情,Git应该仅仅采取这一改变的一个副本。 例如,如果我们对master上的foo.py做了相同的修改,我们完全不需要修改它:它被我们的修改所覆盖。

假设我们改变了README ,我们和他们都修复了foo.py的同样的事情,但他们也改变了doc.txtmain.py 因此,我们最后一组更改是将自己添加的行保留在README ,保持foo.py更改,然后选取doc.txtmain.py更改。 结果是Git将所有这些应用于合并基础提交B的内容。 这给了我们一个新的提交H的内容。 (请注意H因为它可能会反过来困扰我们。)Git将更新索引(下一个要提交的提交进行的地方)和工作树(我们可以看到将要提交或提交的内容)到这个新的内容,准备提交。

现在规则vs squash合并突然很重要,因为如果Git要定期合并提交,它会这样做:

...--B--C--D---H   <-- master (HEAD)
             /
       E--F--G   <-- feature

这个新的合并提交H将提交CD完成的所有工作与提交EFG完成的所有工作结合在一起,将指向提交D ,即master的前一个提示,并提交G ,前一个和当前仍然是当前技巧feature

如果Git要做一个壁球犯下的事情,但是,它说:

Automatic merge went well; stopped before committing as requested
Squash commit -- not updating HEAD
$ 

它使我们做出承诺。 一旦我们做出了这个提交,我们得到了新的提交H ,但是这一次它不会指向DG 这一次,新提交H仅指向D

...--B--C--D---H   <-- master (HEAD)
      
       E--F--G   <-- feature

假设这一切都按照它应该的方式工作,并且我们确实做出提交H 这导致我认为最有可能的情况。

可能的情况

现在让我们看看现在发生了什么,如果我们再次运行git merge --squash feature

Git通过查找合并基础开始与以前一样:分支masterfeature加入的点。 再次提交B

现在Git比较两个分支提示。 这一次, master的尖端是H ,所以两个差异是:

git diff B H
git diff B G

Git现在将结合这些变化。 这一次,我们更改了READMEfoo.pydoc.txtmain.py (请记住,这些都是我们说我们得到了通过合并的一切变化。)与此同时,他们(在feature )改变foo.py我们做同样的方式,改变了doc.txt我们也做了同样的方式,并改变main.py以同样的方式我们做到了。

因此,Git采取了我们所有的改变,而不是他们的改变。 结果完全匹配H Git现在停止,与之前一样。

这一次,当我们运行:

git commit

为了完成这些事情,Git将我们的索引(我们已经提交的提交)与我们的HEAD提交进行比较,并发现它们完全相同,完全相同。 我们已经完成了所有feature 。 Git说“没什么可提交的”,还有“工作树干净”,因为没有什么可提交的,工作树与索引匹配。

不太可能的可能性

另一种方式,我们可以在这里得到相同的效果,而不是先让一个壁球提交H ,那就是如果提交系列EFG “解除自身”足够的话,那就没有关系。 例如,假设F是对foo.py的匹配更改(它可能是提交C的副本),但提交G是提交E的还原。 现在不是触摸doc.txtmain.py ,从BG的变化总和包含在我们原来的BD变化中。 git merge --squash已经承诺合并,但对最终的源代码树没有影响。 我们的索引和工作树将匹配commit Ggit commit根本不会产生新的commit H

就“承诺差异”而言,这与以前是一样的情况:不管什么变化,如果有的话,在另一个分支上引入,我们已经有了。 但是这一次我们没有通过压缩合并获得它:无论如何,我们已经拥有了它。


如果你想压缩提交去头(最后)提交,只是:

git reset --soft HEAD~2 && git commit

输入此命令后,您将被要求将提交消息写入新提交。
这个命令将用你写的新提交消息压缩你的最后两个提交。

然后合并你的分支在这里描述的方式。

链接地址: http://www.djcxy.com/p/49309.html

上一篇: How to squash commits in Git?

下一篇: git: merge two branches: what are the correct steps?