如何在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
:它是其中提交的链,从两种起始master
和feature
在同一时间和向后工作(向左在该曲线图中)中,首先汇集一起。 换句话说,提交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.txt
和main.py
因此,我们最后一组更改是将自己添加的行保留在README
,保持foo.py
更改,然后选取doc.txt
和main.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
,但是这一次它不会指向D
和G
这一次,新提交H
仅指向D
:
...--B--C--D---H <-- master (HEAD)
E--F--G <-- feature
假设这一切都按照它应该的方式工作,并且我们确实做出提交H
这导致我认为最有可能的情况。
可能的情况
现在让我们看看现在发生了什么,如果我们再次运行git merge --squash feature
。
Git通过查找合并基础开始与以前一样:分支master
和feature
加入的点。 再次提交B
现在Git比较两个分支提示。 这一次, master
的尖端是H
,所以两个差异是:
git diff B H
git diff B G
Git现在将结合这些变化。 这一次,我们更改了README
, foo.py
, doc.txt
和main.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.txt
和main.py
,从B
到G
的变化总和包含在我们原来的B
到D
变化中。 git merge --squash
已经承诺合并,但对最终的源代码树没有影响。 我们的索引和工作树将匹配commit G
, git commit
根本不会产生新的commit H
就“承诺差异”而言,这与以前是一样的情况:不管什么变化,如果有的话,在另一个分支上引入,我们已经有了。 但是这一次我们没有通过压缩合并获得它:无论如何,我们已经拥有了它。
如果你想压缩提交去头(最后)提交,只是:
git reset --soft HEAD~2 && git commit
输入此命令后,您将被要求将提交消息写入新提交。
这个命令将用你写的新提交消息压缩你的最后两个提交。
然后合并你的分支在这里描述的方式。
链接地址: http://www.djcxy.com/p/49309.html