如何重新合并已合并的分支?

Joh*_*n M 9 git merge

我有一个提交图,看起来像下面的那个.标记*为的提交代表许多提交.

   A*
   |
   B---------
   |        |
   C*       D*    <- old feature branch
   |        |
   E---------
   |
   F*
   |
   G      <- master
Run Code Online (Sandbox Code Playgroud)

合并提交E未正确完成,并且C*中的某些更改(不是全部)已丢失.如何重做该合并以将更改重新引入当前主服务器?

一切都已被推动(开源项目),所以改变历史不是一种选择.

我尝试从提交C*创建一个补丁并将其应用到主服务器,但由于C*的一些更改已正确合并,并且因为项目自该提交后进化,大约80%的补丁失败.

理想情况下,我们会采用C*中的所有更改,将它们应用于掌握并解决所有冲突.但由于分支已经合并,git不会检测到任何更改,也不允许再次合并.

$ git checkout 5bc5295   # C
HEAD is now at 5bc5295... cleanup

$ git checkout -b "missing-commits"
Switched to a new branch 'missing-commits'

$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

$ git merge missing-commits
Already up-to-date.
Run Code Online (Sandbox Code Playgroud)

Ano*_*noE 8

理想情况下,我们会采用 C* 中的所有更改,将它们应用于 master 并解决所有冲突。

不,理想情况下,您会倒带时间,按照当时的方式进行合并(但这次是正确的),然后重新应用F*更改并最终得到正确的master.

你可以这样做:

git checkout missing-commits
git checkout -b correct-merge
git merge D    # do it right, this time around!
git checkout master
git checkout -b correct-master
git rebase --onto correct-merge wrong-merge correct-master # have fun with the mother of all rebases!
Run Code Online (Sandbox Code Playgroud)

如果您设法在 rebase 期间处理所有冲突,您最终将在 branch 中获得您最初想要的内容correct-master

由于您不想更改历史记录,因此您可以创建一个大补丁并将其应用到当前的master,但我更喜欢这种方法(假设您在工作目录中完成了所有工作yourrepos):

cd yourrepos ; git checkout correct-master ; cd ..
cp -a yourrepos newrepos
rm -rf newrepos/.git
cd yourrepos ; git checkout master ; cd ..
cp -a yourrepos/.git newrepos/
Run Code Online (Sandbox Code Playgroud)

现在,当您输入newrepos并执行 a 时git status,您将在分支上master并准确地看到master和之间的所有更改correct-master,就像您应用了补丁一样。它将捕获已删除的文件、新文件、更改的文件、更改的权限、更改的符号链接等。

理想情况下,如果一切顺利,它将准确显示C. 使用你最喜欢的变体,git add最后一个 nice git commit(或几个,如果你喜欢),你就完成了。历史没有被改写。


Fro*_*don 5

您可以尝试选择:

git checkout master
git cherry-pick B..[last_commit_of_C*]
Run Code Online (Sandbox Code Playgroud)

Git 可能会要求您确认樱桃选择,因为提交位于祖先中。