git交互式rebase南瓜创建了一个全新的分支

时间:2019-05-06 03:04:17

标签: git atlassian-sourcetree git-interactive-rebase

这是我简单明了的历史的最后一部分的图片(从SourceTree开始,时间从下到上):

enter image description here

因此,在这种情况下,我要求SourceTree在最底部的提交(“ Xcode 10.2,Swift 5”)的子级上进行交互式重设,因为我想折叠接下来的两个提交(“ darn,属性列表编码” ”和“ v1.1.1build24”)添加到一个提交中。没有遥控器,因此我可以随意重写历史记录并保持其清洁和有用。

但是当我这样做时,从“ Xcode 10.2,Swift 5”(现有的提交链的副本)分支创建了一大堆新的提交。我不明白为什么,这花了我很多时间来清理它。

这并不是一个新的“分支”(正如我的问题标题中所述);但是通过“ v1.1.2build28”进行的现有提交最终在他们自己的死端分支行上,master现在有了这些新的提交,复制了这些提交,但是没有标签并且带有今天的日期。 / p>

我的问题是:为什么会发生这种情况,我应该怎么做?

2 个答案:

答案 0 :(得分:1)

已按预期完成。

“压缩,属性列表编码”和“ v1.1.1build24”被压缩为一次提交。 Git通过创建一个新提交来实现此功能,新提交的父级为“ Xcode 10.2,Swift 5”,其更改等效于“ darn,属性列表编码”和“ v1.1.1build24”。

“ v1.1.1build25”的父级或基础是“ v1.1.1build24”。现在,新的提交已替换了“ v1.1.1build24”和“织补,属性列表编码”。结果,“ v1.1.1build25”的父级需要成为新提交。否则,在std::bitset上将不再存在“ v1.1.1build24”以上的提交。为了将“ v1.1.1build25”从旧基础移到新基础,Git还为“ v1.1.1build25”生成了一个新提交,其父级现在是压缩的提交,并且其更改与“ v1”的更改相同.1.1build25”。因此,所有其余的后代都将重新创建,因为它们的父母/基地已更改。

Git创建新的提交,就像替换旧的提交一样,但是旧的提交仍然存在于存储库中,只是它们不再可从master访问。但是,诸如“ v1.1.1build25”之类的标签和诸如“ temp”之类的分支仍指向旧提交。由于这些旧提交现在不在当前master上,因此这些标签和分支也不会在master上看到。

答案 1 :(得分:0)

没错。这正是git的工作方式。 Git rebase只是一个小型机器人,它会生成一堆新版本的提交。

有些人甚至是文档都在谈论“重写历史”,这简直是不好的说法。 git根本不可能重写历史记录-一旦提交,就再也无法更改。 git rebase仅有助于将旧历史记录复制到新版本的历史记录。但是-如果您所使用的旧历史记录具有其他标记或分支,即使在重新设置基准后,它们仍将继续指向历史记录。

因此,一个git存储库包含许多无效分支是完全正常的。有时您可以看到它们(因为其他标签/分支仍然引用它们),有时却看不到-但是如果您偶然记住SHA ID,则可以始终引用它们。 (一次,git的垃圾收集器就会出现,并收集历史上真正死掉的部分,什么也没有指向。)

这很好,因为您不会犯任何错误(1)。您始终可以简单地git reset --hard进入历史记录中的某个时刻,因为历史记录永远无法在git中更改。如果您尝试了重新设置,合并或其他操作,但效果却不如预期-如果您记住过SHA(或者标记了它),则可以返回。 (如果没有,则可以通过git reflog找到它)。而且,您总是有几天的时间来进行垃圾收集。

很显然,这对您不利,因为您有很多标记也希望指向新的历史记录。我在Google上搜索了一下,可能有一些工具可以将它们带到新分支,但是我从未使用过这样的工具。试试看或将其视为git具有不可更改的历史的事实。也许有一天,您会开始喜欢上可以没有任何风险的实验:-)

(1)真正丢失工作的唯一方法是在工作目录中进行更改,而不提交它们。如果您尚未提交更改并进行reset --hard,则这些更改将永久丢失,并且没有人会警告您。