理解 git 分支上 rebase 的问题,包括意外和未完成的提交

understanding git issue with rebase on branch with accidental and undone commits

我们的分支有一些问题,过去不知何故搞砸了...以下情况:

             D
    D1-D2-D3-o
     \      \___________
      \                 \  M
       \-M1-M2-D2-F2-M3-D3-o
        \        /
         \      /    F
          \-F1-F2-F3-o

现在我们再次尝试用 M 变基 F,但是我们用 M3 还原的更改 F2 最终丢失了。

    
             D
    D1-D2-D3-o
     \      \___________
      \                 \  M
       \-M1-M2-D2-F2-M3-D3-o
                         \
                          \        F
                           \-F1-F3-o

在分支 F 中我们简单地使用:

git pull --rebase origin master

是否有解释为什么将 F1-F2-F3 变基到 F2-M3 会丢失 F2?

似乎可行的是将 F 中的所有更改压缩到一个提交中,然后进行变基,在这种情况下,F2 中引入的更改仍然存在。

我尝试使用 rebase 交互模式重写 M 的历史并保留合并...我的想法是删除意外提交 (F2) 和还原它 (M3) 但结果没有请给我信心,我没有丢失任何东西。

我还遇到了以下问题(在此处的错误下提到:https://git-scm.com/docs/git-rebase)这让我放弃了重写 master 历史的想法。

The todo list presented by --preserve-merges --interactive does not represent the topology of the revision graph. Editing commits and rewording their commit messages should work fine, but attempts to reorder commits tend to produce counterintuitive results.

我猜测 M 上的 F2 是对 FF2 的挑选,而不是如图所示的合并。

当变基时,git 将挑选所有在 F 但不在 M 中的提交,因为 F2 在两个分支中它不选它。

如果你想保留它,一个解决方案是使用 git rebase:

的所有参数
git rebase --onto M $(git merge-base F M) F
# equivalent to:
# git rebase --onto M D1 F

这将对 F 中的所有提交进行变基,但不会对 MF (D1) 的共同祖先进行变基 ==> F1-F2-F3, 在 M

的末尾

另一种解决方案是进行交互式变基(git rebase --interactive M F),然后在变基待办事项中明确添加pick F2

pick F1
pick F2
pick F3