繁体   English   中英

如何在Git中压缩提交?

[英]How to squash commits in Git?

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

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上具有哪些提交,以及将通过这两个分支的合并基础提交从<branch-name>引入哪些提交。

不过无论如何,我可以做出一个很好的猜测,因为git merge工作方式是将合并基础与两个分支技巧进行比较。 这是进行合并之前的示例图形片段(此时,这是常规合并还是南瓜合并都没有关系):

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

每个大写字母代表一个提交(其真实ID是a9f3c72类的Git哈希ID)。 这里的合并基础提交是提交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进行了相同的更改, foo.py我们根本不需要它们的更改:它已包含在我们的更改中。

假设我们更改了README并且我们和他们都在foo.py修复了相同的问题,但是他们也更改了doc.txtmain.py 因此,最后一组更改是将添加的行保留在README ,保留foo.py更改,并选择doc.txtmain.py更改。 结果是Git将所有这些都应用于合并基础提交B的内容。 这为我们提供了新提交H的内容。 (请注意H因为它可能会再次困扰我们。)Git将索引(下一次提交的位置)和工作树(我们可以看到将要或将要提交的位置)更新到这个新位置内容,准备提交。

现在,常规与壁球合并突然变得很重要,因为如果Git要进行常规合并提交,它将执行以下操作:

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

这个新的合并提交 H将提交CD完成的所有工作与提交EFG完成的所有工作组合在一起,将指向既是 master的前一个提交D ,又是提交到G的前一个仍是当前的G feature

但是,如果Git要进行壁球提交,那么它会在说出以下内容后停止:

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

它使我们做出承诺。 一旦我们做出这个承诺,我们得到了新的提交H ,但这次回指向两个 D G 这次,新提交H 指向D

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

假设这一切都按应有的方式进行 ,实际上我们确实进行了commit 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 包含在我们原来的B至- D的变化。 git merge --squash承诺要合并,但是对最终的源代码树也没有影响。 我们的索引和工作树将匹配提交Ggit commit根本不会产生新的提交H

在“提交差异”方面,这与以前的情况相同:任何更改(如果有的话)都会引入另一个分支,我们已经有了。 但是这次我们并没有通过壁球合并得到它:反正我们已经有了它。

如果要压缩提交,请转到HEAD(last)提交,然后执行以下操作:

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

输入此命令后,将要求您将提交消息写入新的提交。
该命令将使用您编写的新提交消息将最后两个提交压缩为一个。

然后合并你的分支它是如何描述在这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM