在 Git 中混合 merge-basing 两个历史尾巴

Intermingling merge-basing two history tails in Git

我有两个 Git 存储库,它们具有不同的历史记录。经过大量的研究和大量的修补,我总结了一个看起来像这样的历史(使用 YYYY-DD 作为伪 commit-hashes):

HEAD---2016-09---2016-08---2016-07---2016-06
                     \-----2015-10---2015-09

请注意,此历史记录似乎有两个 "roots",因为 2015-10 序列位于中间 merged/grafted。重要的是 2016-07 历史和 2015-10 历史 中的文件包含完全不同的文件,没有任何共同点。

我想将此历史记录合并到一个完整的提交行中,按原始提交顺序从最旧到最新,没有跳过(即消失的内容稍后重新出现)。换句话说,这就是我想要结束的:

HEAD---2016-09---(2016-08)---2016-07---2016-06---2015-10---2015-09

我将 (2016-08) 放在 parentheses 中,因为作为合并提交,如果一切正常,我什至认为我不需要它。

起初我想做一个 git replace --edit 2016-08 来删除它的 2015-10 parent,然后 git replace --edit 2016-062015-10 作为它的 parent(见 ),果然,在做了 git filter-branch --tag-name-filter cat -- --all 之后,我得到了一个 看起来 像我想要的序列。

但是后来我开始想:因为两个"tails"里面的内容完全不一样,会不会2015-10"disappear"里面的内容在2016-06然后"come back" 在 2016-08 中? (我承认我现在无法立即验证它是否成功;我删除了那个尝试,今晚我太累了,不想再做一次。)我如何有效地 "merge"(在日常意义上)两条尾巴,好像2016-06里的内容加在了2015-10里的内容上?也就是说,任何替换 2016-06 的提交都将包含 2015-10 中的所有内容以及 原始 2016-06 中的内容?但是我希望新的 2016-06 具有其原始提交日期、日志消息等

然后,完成后,如何从历史 中删除 "merge" 提交 2016-08,因为它不再需要了?我假设我可以使用 中的 git rebase --onto 2016-08~ 2016-08 HEAD。我在最初的尝试中尝试过,但它没有用——我认为它与 2016-072016-06 中的 "disappeared" 的内容有关,因为我只是重新缝合了尾巴的顺序不同,但我不确定。

如果这是一个重复的问题,我深表歉意,但经过几个小时的工作并深入研究历史(并小心翼翼地在 vi 中四处探索),我今天有一点 "Git fatigue"。提前谢谢你。

在一个简化的例子中,我能够

git checkout -b middle 2016-07
git rebase 2015-10

这会在 2015-10 的基础上重播您的 2016-07 和 2016-06

git checkout master

假设您的主人指向 2016-09 或后代

git rebase middle

在我们刚刚创建的新中间层之上重播 2016-09(或更多,取决于您的主人)。此 rebase 还将丢弃合并提交。

如果,如您所说,the files in the 2016-07 history and the 2015-10 history contain completely different files with nothing in common这应该会给您一个没有冲突的美好历史。