在THIS问题中,我询问{{ original }} <br>
{{ translate }}
<br><br>
<a href="{% url 'home' %}">Home</a>
与git merge branchname
之间的区别以及它对项目历史的影响。现在跟进:
是否可以在将此分支推送到远程后更改此合并提交类型(来回git merge branchname --squash
)?
背景故事当然是我与错误的旗帜合并,现在是时候自己清理......
答案 0 :(得分:1)
简短的回答是否定的,除非通过强制推动。
要理解为什么,请考虑以下事实:在Git中, merge 一词充当动词,合并,同时也充当形容词或名词:合并提交(提交类型&#34;合并&#34;)或合并(合并提交)。
当我们使用动词形式来合并时,我们的意思是组合两个不同的变更集合,这些变化是针对某些常见的基础进行的。这是git merge
(进行真实,非快进,合并时)和 git merge --squash
的动词形式。所以在这一步,两者的行为方式相同。 (到目前为止,我们还不错。)
git merge
或git merge --squash
完成&#34;合并&#34;但是,它们采取了两种不同的路径。正常的非压缩合并会生成合并提交,这是一个具有两个父提交ID的提交。通过运行--squash
- 正常的单父提交,git commit
合并会让您更好地做出决定。无论哪种方式,您都会获得提交,但关于Git提交的事情是它由哈希ID 唯一标识,并且其哈希ID由中的每一位信息确定>提交。至关重要的是,这些信息包括父哈希或哈希值。
这意味着,当你或Git发表这篇文章时,&#34;合并为动词&#34;提交,你冻结提交的ID,两个父项(如果是合并提交)或单个父项(如果是正常的非合并)。与每个 Git对象一样,一旦根据内容计算哈希ID,就无法更改哈希ID和内容的配对。如果您更改了内容,则会创建一个 new 对象,该对象会获得新(和不同的)ID。
因此,您可以在git push
之前进行提交,使用相同的树进行新的提交,但只使用一个父级或父母双方 - 无论哪一个都没有时间周围 - 因此,真的,真的,合并提交&#34;和&#34;并非真正合并壁球提交&#34;存储库中的对象。然后,您可以选择其中一个并将其发送到某个远程,并要求远程设置其自己的名称,例如master
或develop
或远程上的任何名称,以指向一个提交
但是现在,您已经将这两个哈希ID中的一个发送到远程,并要求它将其名称设置为指向一个提交。让我们说,具体来说,您要求遥控器设置名称M
。您可以发送其他哈希ID(如果您愿意,可以先进行其他提交),并要求远程设置一些其他名称,例如N
,以指向其他哈希ID;一般来说都可以。但是,如果您要求远程设置M
到另一个哈希ID,则远程首先会查看M
的当前设置。它会看到使M
指向新提交而不是旧提交实际上丢失旧提交,因为新提交的哈希ID没有旧提交在其祖先中提交哈希ID(新提交的哈希ID不是M
的当前哈希ID,也不是新提交的父级或父级M
,他们的父母也不是M
,等等。
因此,远程&lt; remote&gt;将拒绝git push <remote> <hash>:M
作为非快进。要让其他Git将其M
设置为新哈希,丢弃旧哈希,必须向其发送强制推送操作。这并不保证遥控器会服从,但它确实告诉遥控器你想要从他们的M
中丢弃一些提交。
这里的危险是:
您可以放弃先前推送的提交(这是您的意图),转而支持您的新哈希(这样更好),但也许其他人已使用该远程选择了您的旧的合并,所以现在它已经在互联网上传播。这给每个人带来了问题。
您可能会丢弃 more 而不仅仅是您推送的合并。假设Bob在该提交上添加了一个提交,并且Carol在Bob的上面添加了一个提交。你的强制推送将丢弃你的旧提交以支持你的新提交,但它还会丢弃在旧提交之上构建的Bob和Carol的提交。
如果您确定Bob和Carol不存在并且没有其他人拥有您的旧(错误合并样式)提交,那么它足够安全以强制推送该提交并将其替换为改进了一个。但如果没有,它毕竟不安全。您可以查看--force-with-lease
选项作为替代选项,但如果其他人选择了您的错误提交,则该错误提交可能会继续返回,类似病毒,会困扰您。