举个例子:
我在一个主题分支中有一些工作,现在我准备合并回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
好吧,这是一个老问题,@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
拖鞋!