如果要重新绑定保持合并提交的分支,则传递--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
答案 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~2
是origin/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