我有一个历史非常混乱的分支
它提交1 - X,然后是(M length)的合并提交。
我想在合并提交时重新定义,所以我不必重播合并冲突产生的所有合并冲突。
有什么办法吗?
或者我应该放弃并挑选所有好的提交到另一个分支?
答案 0 :(得分:1)
所以你有
A -- B -- C -- D -- M -- E -- F -- G <--(master)
/
... X -- X -- X
并且您要删除X
提交(和M
),对吗?
有几种方法可以做到这一点。这是一个历史重写,意思是两个人:
1)如果分支是共享的(在远程存储库中,或者我想通过传递bundle文件),那么你需要了解“上游rebase”的问题;请参阅git rebase
文档,但总的来说,您可能需要与回购的其他用户进行协调。
2)如果您有其他引用您引用的提交,它们也需要更新
所以说,一种方法是
git rebase -i master~4 master
(其中master~4
在此示例中起作用,但一般来说,您需要的是一个解析为提交D
)的表达式。这将启动文本编辑器并向您显示“todo list”())
pick 12345678 one of the X commits
pick 23456789 another X commit
pick 01234567 yet another X commit
pick 34567890 commit E
pick 45678901 commit F
pick 54321098 commit G
请注意M
已被省略 - 因为默认情况下rebase
想要消除合并。在X
xommits的行上,将第一个单词从pick
更改为drop
(或只删除该行)。然后退出编辑器。
如果任何提交E
,F
或G
影响了任何X
触及的相同代码块,您将必须解决它就像合并冲突。但是一旦事情得到解决,你应该得到
A -- B -- C -- D -- E' -- F' -- G' <--(master)
另一种避免交互式工作的变体(但可能有点难以思考)是
git rebase --onto master~4 master~3 master
这将选择从master
可到达的提交但无法从主要的第三祖先(M
)到达以进行重写 - 这些提交是E
,F
和{{ 1}} - 它会将G
用作新父级,“踩过”D
。
我应该注意,这些方法(以及您可能会拼凑在一起的任何其他方法)实际上并不删除M
或X
提交,而重写的提交是完全相同的新提交到旧提交(例如,M
是E'
的“重播”,但它仍然是一个新的独特提交。在执行此操作之后(默认情况下,暂时之后),您仍然可以使用reflog返回旧历史记录。