在一个提交窗口上重新定义

时间:2018-04-20 16:47:53

标签: git

我有一个历史非常混乱的分支

它提交1 - X,然后是(M length)的合并提交。

我想在合并提交时重新定义,所以我不必重播合并冲突产生的所有合并冲突。

有什么办法吗?

或者我应该放弃并挑选所有好的提交到另一个分支?

1 个答案:

答案 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(或只删除该行)。然后退出编辑器。

如果任何提交EFG影响了任何X触及的相同代码块,您将必须解决它就像合并冲突。但是一旦事情得到解决,你应该得到

A -- B -- C -- D -- E' -- F' -- G' <--(master)

另一种避免交互式工作的变体(但可能有点难以思考)是

git rebase --onto master~4 master~3 master

这将选择从master可到达的提交但无法从主要的第三祖先(M)到达以进行重写 - 这些提交是EF和{{ 1}} - 它会将G用作新父级,“踩过”D

我应该注意,这些方法(以及您可能会拼凑在一起的任何其他方法)实际上并不删除MX提交,而重写的提交是完全相同的新提交到旧提交(例如,ME'的“重播”,但它仍然是一个新的独特提交。在执行此操作之后(默认情况下,暂时之后),您仍然可以使用reflog返回旧历史记录。