你如何通过rebase保持分支机构共享相同的历史记录?

问题描述 投票:1回答:1

如果我从这段历史开始:

* 505421e - (HEAD -> stage4) go to stage 4
* 307978f - (stage3) go to stage 3
* d8ab213 - steb b
* 49cbef9 - (stage2) step a
* 6e4a2ed - (stage1) go to stage 1
* 3ca2d7d - do something
* 5ce596d - (stage0) go to stage 0
* 0c8487b - foo
* ccfb7c9 - bar

我做git rebase -i ccfb7c9以改变foo提交,然后分支stage0–stage3将不再具有与stage4相同的提交历史记录,并且将不会有更新的foo提交。如何让他们拥有相同的历史?

git git-rebase
1个回答
1
投票

你是对的。不幸的是,Git没有内置任何“正确的方法”。在这里定义“正确”有点困难,虽然我在脑海中有一个特定的定义,并开始编写一个程序来做到这一点。对于所有奇怪的角落情况来说太难了,我放弃了它。

这里的根本问题是git rebase通过复制提交来工作,就好像通过git cherry-pick(使用交互式rebase让你在此过程中进行一些额外的更改).2新副本具有新的,不同的哈希ID .3一旦制作副本,Git重新指向一个分支名称 - 当前分支,无论您何时启动git rebase到最后一次这样复制的提交。

换句话说,在这种情况下,你有Git副本:

  • 0c8487b - foo
  • 5ce596d - (stage0) go to stage 0
  • 3ca2d7d - do something
  • ...
  • 505421e - (HEAD -> stage4) go to stage 4

按顺序(最早到最晚),一次一个。在第一步你做了一些改变 - 只要你改变一些东西并不重要 - 这样新的提交会得到一些新的,不同的哈希ID,比如cccccc1(可能实际上并不是这样,但这让我们将其称为“新提交1”)。这个新提交的父提交是ccfb7c9,它是标记为bar的提交,因此新历史记录在此时重新加入旧历史记录。

然后Git复制第二个提交,5ce596d - (stage0) go to stage 0,它变成了cccccc2cccccc2的父母是cccccc1,单独与5ce596d完全不同,迫使这是一个不同的承诺。 Git继续复制所有八个提交,最后一个可能成为cccccc8;然后Git更改名称stage4,以便命名提交cccccc8

因此,当您现在通过从Git找到的名称stage4的提交开始查看历史记录时,您会看到新的历史记录。但是Git没有改变任何其他名称:例如,stage3仍然识别提交307978f,而stage0仍然识别提交5ce596d。因此,如果您从任何这些名称开始查看历史记录,您会看到原始提交系列。

你需要的是让Git将每个标签从其原始哈希移动到它的新哈希。问题出现在识别所有这些事情上:哪些标签应该移动? (你可能希望有些人故意保留旧的提交,有些人要移动。)就此而言,哪个提交是正确的新提交?如果在交互式rebase期间,我选择拆分一些提交并合并其他提交,该怎么办?

简单而强力的解决方案是手动强制您想要更改的任何名称,以指向新提交。运行git log --all --decorate --oneline --graph并记下每个名称的旧的和新的提交ID,然后运行:

git branch -f stage0 newhash0
git branch -f stage1 newhash1
git branch -f stage2 newhash2
git branch -f stage3 newhash3

你完成了或者,只需完全删除其中一些分支名称,因为您可以从stage4(自动移动)和向后工作开始查找提交。


1我喜欢的定义涉及构造分支名称,因此名称具有比“提交的原始指针”更多的语义。这种结构的形式也很难:它应该使用名称层次结构,还是应该使用git config条目将分支名称分组为“超级分支”?

2有些git rebase命令字面上运行git cherry-pick而有些则没有。交互式rebase是真正运行git cherry-pickgit commit --amend和其他棘手项目的案例之一。

3任何Git对象的哈希ID都严格按其内容确定,因此如果“copy”与原始位100%相同,则表示相同的哈希ID,即只需重新使用原版的。但是只要你进行任何更改,序列中某些提交的哈希ID就会发生变化,这会强制每个“下游”(子)提交都有一个不同的父哈希ID,这也会改变每个下游提交。

© www.soinside.com 2019 - 2024. All rights reserved.