更新 - 从未如此简单,不是吗?
我发现我建议的原始说明中有一个缺陷:当使用路径参数执行checkout 时,您可能希望从您的工作路径中删除一个文件,因为它不在您正在检查的提交中出去;但是你可能会感到惊讶......
与任何历史重写一样,值得注意的是,您可能不应该对您已经推送的任何合并执行此操作(使用任何这些答案中的任何方法,包括这个答案)。那就是……
前面的答案很好,但是如果您想避免使用(或需要知道)管道命令或其他 git 内部工作 - 如果这对您来说比拥有像 Jared 的解决方案这样的单线更重要 - 那么这是另一种选择:
这个解决方案的整体结构类似于 zeeker 的,但他使用管道命令来操纵 HEAD 或“欺骗” git 以完成合并,我们将只使用瓷器。
和以前一样
* (master) Merge Commit
| \
| * (feature) fixed something
* | older commit on master
让我们开始吧:
1) 标记旧的合并
我们实际上会使用这个标签。 (如果你想写下缩写的 SHA1,那会起作用;但这里的重点是使修复对用户友好,所以...)
git tag badmerge master
现在我们有
* (master) [badmerge] Merge Commit
| \
| * (feature) fixed something
* | older commit on master
2) 从 master 的历史中取出合并
git branch -f master master^
足够简单:
* [badmerge] Merge Commit
| \
| * (feature) fixed something
* | (master) older commit on master
3) 开始新的合并
git checkout feature
如果我们现在只运行git merge master,我们知道合并会失败;但我们不想重做手动冲突解决。如果我们有办法将 badmerge 中的数据叠加到新的合并提交上,我们就万事大吉了……我们做到了!
开始合并 (a) 不创建要清理的冲突状态,但 (b) 保持合并提交打开以便我们可以“修复”它:
git merge --no-commit --strategy=ours master
4) 覆盖 badmerge 中已解析/合并的数据
确保我们位于 repo 的根目录中,然后我们可能会执行 git checkout badmerge -- .(请注意,我们提供了一个路径 (.) 到 git checkout,因此它只会更新工作树和索引) ;但这实际上可能是一个问题。
如果合并导致文件被删除(但它们现在在我们的工作树中),那么上面的命令不会删除它们。因此,如果我们不确定,我们有几个选项可以避免这种可能性:
我们可以先清除我们的工作树...但我们确实需要小心不要清除 .git 文件夹,并且可能需要对忽略文件中的任何内容进行特殊处理。
在简单的情况下 - .git 是唯一的 .-文件,没有任何东西被忽略 - 我们可以做
rm -rf *
git checkout badmerge -- .
或者,如果这看起来太冒险,另一种方法是跳过rm,执行git checkout badmerge -- .,然后与 badmerge 进行比较,看看是否需要清理。
5) 完成合并
git commit
git tag -d badmerge