git - 如何使用 git 展平两个顶级合并提交
问题描述
我最近遇到了一个我不知道如何处理的 git 场景。首先让我们设置场景。
理想的工作流程
假设您正在维护一个大型开源项目的分支,上游正在使用拉取请求 (PR) 进行开发。由于上游正在做 PR,他们的 git 历史有很多合并提交。
您必须定期将您的树与上游同步。通常情况是这样的:
git checkout -b sync
git pull upstream master
- 修复合并冲突,在
git add
ing 冲突文件之前,然后git commit
.
此时,您在树的顶部有一个整洁的小合并提交。嵌套在里面的是上游的所有提交和合并。你运行你的持续集成测试 (CI),它们通过并且分支被合并到你的 fork 的主分支中。精彩的。
有问题的场景
git checkout -b sync
git pull upstream master
- 您修复合并冲突,
git add
以及git commit
它们。 - 你运行你的 CI 并且测试失败,因为上游破坏了一些东西。
- 两天后,上游解决了这个问题。
git pull upstream master
- 再次修复合并冲突。
此时,您的sync
分支包含您编写的两个合并提交。每个单独的合并提交都包含上游的各种提交和合并。
您现在可以运行 CI 并合并,但您不应该这样做,因为您的第一次合并提交会干扰 future git bisects
。理想情况下,您将有一个合并提交,它是两个按顺序合并提交的总和。
如何将这两个合并提交合并为一个,但保留上游的 git 历史记录?
笔记
git rebase --preserve-merges
是a)已弃用,和b)全部或全部。您不能有选择地保留所有上游的合并,而是展平您的合并。
我尝试使用git rebase --rebase-merges -i origin/master
并标记第二个合并f
以进行修复,但这并没有达到预期的效果。我对从未接触过的文件进行了合并提交。
一种解决方案是在上游已修复后从头开始重做整个合并。问题是,即使rerere
这样也会有很多工作。在这些上游同步中,您最终会修复不是合并冲突的东西,而是(例如)编译或逻辑错误。因为这些修复是合并冲突(单独提交)的次要修复,rerere
所以不会为它们记录自动解决方案。
解决方案
如果我理解正确,您需要一个合并提交:上游树,包括最近的修复,与您的sync
分支合并。所以,这就是您应该做的:将您的同步分支重置为原始合并之前的提交,然后再次执行合并。
如果您在原始合并之后但在上游修复可用之前对同步分支进行了其他更改,您可以先将这些提交重新设置为原始合并之前的提交:
git checkout -b sync
git rebase --onto ${PREMERGECOMMIT} ${MERGECOMMIT}
git pull upstream master
推荐阅读
- python - 尝试用python以两种方式计算列表列表中的重复项,但得到不同的答案
- java - 如何添加基于扫描仪创建多个扫描仪
- pandas - 如何使用 df.add_suffix 为 Pandas 中的重复列名添加后缀?
- laravel - 更新并显示控制器用户“触摸”的列
- bash - 启动屏幕会话并在其中运行命令
- browser - 带有无限循环的浏览器组件
- git - 来自 SCM 的 Jenkins 管道脚本:git checkout 错误:无法检索提交消息
- javascript - 如何以编辑形式在图像预览中检索保存图像?
- javascript - 使用 vuetify 在 nuxt.js 中滚动事件
- video - 在移动应用程序中查找视频流的视频播放速度