举个例子:

我在一个主题分支中有一些工作,现在我准备合并回master:

* eb3b733 3     [master] [origin/master]
| * b62cae6 2   [topic]
|/  
* 38abeae 1

我执行合并从主,解决冲突,现在我有:

*   8101fe3 Merge branch 'topic'  [master]
|\  
| * b62cae6 2                     [topic]
* | eb3b733 3                     [origin/master]
|/  
* 38abeae 1

现在,合并花费了我一些时间,所以我再次取回并注意到远程主分支有新的变化:

*   8101fe3 Merge branch 'topic'  [master]
|\  
| * b62cae6 2                     [topic]
| | * e7affba 4                   [origin/master]
| |/  
|/|   
* | eb3b733 3
|/  
* 38abeae 1

如果我尝试git rebase origin/master from master,我被迫再次解决所有冲突,我也失去了合并提交:

* d4de423 2       [master]
* e7affba 4       [origin/master]
* eb3b733 3
| * b62cae6 2     [topic]
|/  
* 38abeae 1

是否有一种干净的方法来重新调整合并提交,使我最终得到如下所示的历史记录?

*   51984c7 Merge branch 'topic'  [master]
|\  
| * b62cae6 2                     [topic]
* | e7affba 4                     [origin/master]
* | eb3b733 3
|/  
* 38abeae 1

当前回答

好吧,这是一个老问题,@siride已经给出了一个公认的答案,但这个答案在我的情况下还不够,因为——save -merges迫使您再次解决所有冲突。我的解决方案是基于@Tobi B的想法,但有精确的一步一步的命令

我们将从最初问题中发现的相同状态开始:

*   8101fe3 Merge branch 'topic'  [HEAD -> master]
|\  
| * b62cae6 2                     [topic]
| |
| | * f5a7ca8 5                   [origin/master]
| | * e7affba 4
| |/  
|/|   
* | eb3b733 3
|/  
* 38abeae 1

请注意,我们在master之前有2次提交,所以选择是行不通的。

First of all, let's create the correct history: git checkout -b correct-history # create new branch to save master for future git rebase --strategy=ours --preserve-merges origin/master We use --preserve-merges to save our merge commit in history. We use --strategy=ours to ignore all merge conflicts as we don't care about what contents will be in that merged commit, we only need a nice history. The history will look like this (ignoring master): * 51984c7 Merge branch 'topic' [HEAD -> correct-history] |\ | * b62cae6 2 [topic] * | f5a7ca8 5 [origin/master] * | e7affba 4 * | eb3b733 3 |/ * 38abeae 1 Let's get the correct index now. git checkout master # return to our master branch git merge origin/master # merge origin/master on top of our master We may get some additional merge conflicts here, but that would only be conflicts from files changed between 8101fe3 and f5a7ca8, it doesn't include already resolved conflicts from topic History will looks like this (ignoring correct-history): * 94f1484 Merge branch 'origin/master' [HEAD -> master] |\ * | f5a7ca8 5 [origin/master] * | e7affba 4 | * 8101fe3 Merge branch 'topic' | |\ | | * b62cae6 2 [topic] |/ / * / eb3b733 3 |/ * 38abeae 1 The last stage is to combine our branch with correct history and branch with correct index git reset --soft correct-history git commit --amend We use reset --soft to reset our branch (and history) to correct-history, but leave index and working tree as is. Then we use commit --amend to rewrite our merge commit, that used to have the incorrect index, with our good index from master. In the end we will have this state (note another id of top commit): * 13e6d03 Merge branch 'topic' [HEAD -> master] |\ | * b62cae6 2 [topic] * | f5a7ca8 5 [origin/master] * | e7affba 4 * | eb3b733 3 |/ * 38abeae 1

其他回答

看起来你要做的是删除第一个合并。您可以执行以下步骤:

git checkout master      # Let's make sure we are on master branch
git reset --hard master~ # Let's get back to master before the merge
git pull                 # or git merge remote/master
git merge topic

那会给你你想要的。

这里有两种选择。

一种是进行交互式的重基并编辑合并提交,手动重做合并并继续重基。

另一种是在git rebase上使用——rebase-merges选项,手册中描述如下:

默认情况下,rebase将简单地从todo列表中删除合并提交,并将rebase提交放入单个线性分支中。使用——rebase-merge, rebase将尝试通过重新创建合并提交来保留将要重基的提交中的分支结构。在这些合并提交中任何已解决的合并冲突或手动修改都必须手动解决/重新应用。”

好吧,这是一个老问题,@siride已经给出了一个公认的答案,但这个答案在我的情况下还不够,因为——save -merges迫使您再次解决所有冲突。我的解决方案是基于@Tobi B的想法,但有精确的一步一步的命令

我们将从最初问题中发现的相同状态开始:

*   8101fe3 Merge branch 'topic'  [HEAD -> master]
|\  
| * b62cae6 2                     [topic]
| |
| | * f5a7ca8 5                   [origin/master]
| | * e7affba 4
| |/  
|/|   
* | eb3b733 3
|/  
* 38abeae 1

请注意,我们在master之前有2次提交,所以选择是行不通的。

First of all, let's create the correct history: git checkout -b correct-history # create new branch to save master for future git rebase --strategy=ours --preserve-merges origin/master We use --preserve-merges to save our merge commit in history. We use --strategy=ours to ignore all merge conflicts as we don't care about what contents will be in that merged commit, we only need a nice history. The history will look like this (ignoring master): * 51984c7 Merge branch 'topic' [HEAD -> correct-history] |\ | * b62cae6 2 [topic] * | f5a7ca8 5 [origin/master] * | e7affba 4 * | eb3b733 3 |/ * 38abeae 1 Let's get the correct index now. git checkout master # return to our master branch git merge origin/master # merge origin/master on top of our master We may get some additional merge conflicts here, but that would only be conflicts from files changed between 8101fe3 and f5a7ca8, it doesn't include already resolved conflicts from topic History will looks like this (ignoring correct-history): * 94f1484 Merge branch 'origin/master' [HEAD -> master] |\ * | f5a7ca8 5 [origin/master] * | e7affba 4 | * 8101fe3 Merge branch 'topic' | |\ | | * b62cae6 2 [topic] |/ / * / eb3b733 3 |/ * 38abeae 1 The last stage is to combine our branch with correct history and branch with correct index git reset --soft correct-history git commit --amend We use reset --soft to reset our branch (and history) to correct-history, but leave index and working tree as is. Then we use commit --amend to rewrite our merge commit, that used to have the incorrect index, with our good index from master. In the end we will have this state (note another id of top commit): * 13e6d03 Merge branch 'topic' [HEAD -> master] |\ | * b62cae6 2 [topic] * | f5a7ca8 5 [origin/master] * | e7affba 4 * | eb3b733 3 |/ * 38abeae 1

从合并提交中 挑选新的变化应该很容易 复制你的东西 重做合并和解决冲突,只需从您的本地副本复制文件;)

考虑到我刚刚花了一天时间试图解决这个问题,并在同事的帮助下找到了解决方案,我想我应该加入进来。

我们有一个很大的代码库,我们必须处理2个分支同时被大量修改。这里有一个主分支和一个副分支。

当我将次要分支合并到主分支中时,工作仍在主分支中继续,当我完成时,我不能推动我的更改,因为它们是不兼容的。

因此,我需要“重新调整”我的“合并”。

我们最终是这样做的:

1)记录SHA。例:c4a924d458ea0629c0d694f1b9e9576a3ecf506b

git log -1

2)创建正确的历史,但这将破坏合并。

git rebase -s ours --preserve-merges origin/master

3)做好SHA记录。例:29 dd8101d78

git log -1

4)现在重置到之前的位置

git reset c4a924d458ea0629c0d694f1b9e9576a3ecf506b --hard

5)现在将当前master合并到您的工作分支中

git merge origin/master
git mergetool
git commit -m"correct files

6)既然你有正确的文件,但历史记录是错误的,那就找正确的 在更改的顶部使用:

git reset 29dd8101d78 --soft

7)然后——修改原始合并提交的结果

git commit --amend

拖鞋!