如何在保留合并更改的同时删除合并提交?

How to remove merge commits while keeping merged changes?

我有来自我的仓库的提交日志。您可以看到“Merge branch...into...”提交。在这些提交之后,分支被合并。

我需要删除合并提交,但不放弃更改。 默认变基不显示合并提交。

如果你想在不包括合并提交的情况下应用提交的更改(正如 Roland Smith 指出的那样,这通常被认为是不好的做法)你可以使用 git rebase 和以下工作流程:

  1. 签出你想要更改的分支(假设是 master):git checkout master
  2. 将 master 重置为要撤消的合并之前的提交:git reset --hard <hash of prior commit>。确保您正在处理的分支上没有未提交的更改,否则此命令会清除它们。
  3. 签出包含您想要 "merge" 掌握的更新的分支,而不实际合并它(我们称之为 dev):git checkout dev.
  4. 变基 dev 到 master 上。这将使 dev 的 HEAD 提交成为 master 指向的最新提交的上游:git rebase master(有关更多信息,请参阅 the docs)。
  5. 修复变基过程中导致的任何合并冲突(它们也会在正常合并中发生)。
  6. rebased 分支现在应该在 master 上的最新提交之后拥有所有提交。要将其移植到 master,请检查 master (git checkout master) 并合并新分支 git merge dev。这将把更改拉到 master 上而不添加合并提交。
  7. 一旦您确定更新的 master 分支看起来没问题,您也必须更新任何远程存储库上的分支。因为你正在撤销之前的历史,所以当你推送分支时,你必须使用 --force(或 -f)标志让远程仓库接受更改,即:git push origin master --force

仅此而已。执行此操作后,从 master 分支出来的 dev 上的提交现在应该位于上面的合并前提交的上游。

注意:运行 rebase 将永久更新已更改分支的提交历史记录。为了安全起见,我建议采用以下两种方法中的一种:

  1. 根据@Dacav 的建议,在更新任何内容之前跟踪每个分支的提交哈希。如果事情进展顺利,那么只需 运行 git reset --hard <original_commit_hash> 将分支放回原始提交即可。
  2. 在变基之前为指向原始提交的两个分支制作备份副本:

    git checkout -b master_bk git checkout -b dev_bk