允许在git rebase中合并不相关的历史记录

时间:2017-03-24 18:18:07

标签: git git-rebase

如果要重新绑定保持合并提交的分支,则传递--preserve-merges标志。当你在git中合并不相关的历史时,你需要传递--allow-unrelated-histories标志。

如果您在现有合并来自不相关的历史记录时执行git rebase --preserve-merges,则会失败:

  

致命:拒绝合并不相关的历史

如果您尝试git rebase --preserve-merges --allow-unrelated-histories,则会失败:

  

错误:未知选项'allow-unrelated-histories'

还有其他方法告诉rebase允许合并吗?

编辑:这是一个最小的复制:https://github.com/vossad01/rebase-unrelated-merge-reproduction

要重现结帐master,请执行:

git rebase --preserve-merges --onto origin/a-prime HEAD~2

4 个答案:

答案 0 :(得分:9)

git rebase合并失败时,它不会中止rebase,因此您有机会进行干预。

如果您愿意手动解决此问题,可以按如下方式完成合并:

git merge --allow-unrelated ORIGINAL_BRANCH_THAT_WAS_MERGED --no-commit
git commit -C ORIGINAL_MERGE_COMMIT
git rebase --continue

理想情况下,Git可以在没有人工干预的情况下处理此问题。

答案 1 :(得分:6)

蛮力方法是强制使用一个共同的根 - 因为你试图修改根,没有内容历史记录,所以做一个nonce空提交并告诉git它是历史的父级你正在合并:

git rev-list --all --max-parents=0 \
| awk '{print $0,empty}' empty=`:|git mktree|xargs git commit-tree` \
> .git/info/grafts
git rebase here
rm .git/info/grafts

答案 2 :(得分:1)

  

要重现结帐主人,请执行:

     

git rebase --preserve-merges --onto origin/a-prime HEAD~2 -i

git-rebase文档说不合并-i--preserve-merges

  

[ - preserve-merges]在内部使用--interactive机器,但明确地将它与--interactive选项结合使用通常不是一个好主意,除非你知道你在做什么(参见下面的BUGS)。

但即使没有-i,它仍会以fatal: refusing to merge unrelated histories失败。

部分问题是HEAD~2origin/a-prime的直接祖先。您的测试回购看起来像这样:

1 [master]
|
2
|\
| |  3 [origin/a-prime]
| |  |
| 4 / [origin/b]
|  /
| /
|/
5 [origin/a]
HEAD~2的{​​p> master为5. origin/a-prime为3.您的命令相当于:

git rebase -p --onto 3 5

5是3的直接祖先,所以命令没有多大意义。如果它起作用,那就会做一些奇怪的事情。

  

我最近遇到的几次案例是将项目文档从GitHub Wiki移动到GitHub页面(当网站已经存在时)。

这是对rebase的不当使用。 Rebase将并行历史转换为线性历史,基本上假装一组更改始终在另一组上完成。这对于在工作时保持功能分支最新的事情是很好的,如果你没有一堆中间的合并提交除了更新分支之外什么也不做,那么簿记和审查会更容易。对于任何阅读代码并在将来提交历史记录的人来说,这些只是噪音。

但是当你有两个真正不同的历史时,最好把它们留作不同的历史。合并它们可以说明正确的故事:网站和文档是分开开发的,但后来组合成一个单元。

1 - 3 - 5
         \
  2 - 4 - 6 - 7 - 8 [master]

您可以使用git log --topo-order以拓扑顺序(8,7,6,5,3,1,4,2)单独查看它们,或者您可以按日期顺序(8,7,7, 6,5,4,3,2,1),git log默认。像gitk或GitX这样的历史可视化工具会同时显示两个订单。

在另一个之上重新定位一个谎言说:我们在网站上工作,然后我们处理文档,然后在某个时候(你必须找到一个点)并且由于某种原因我们工作了网站和文档在一起。

1 - 3 - 5 - 2 - 4 - 6 - 7 - 8 [master]

这会丢失重要信息,并且令人费解的是为什么某些变化在未来变得更加困难。

进行合并,这是正确的。

答案 3 :(得分:0)

同步两个分开的分支的唯一方法是将它们重新合并在一起,从而产生一个额外的合并提交和两组提交,这些提交包含相同的更改(原始更改和来自您的基于重新创建分支的更改)。不用说,这是一个非常令人困惑的情况。

因此,在运行git rebase之前,请始终问自己:“是否还有其他人在看这个分支?”如果答案是肯定的,请从键盘上放开手,然后开始考虑进行无损更改的方法(例如,git revert命令)。否则,您可以安全地随意重写历史记录。

参考:https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing