请注意,现有的提交不能更改,所以给出:
...--α--A------B <-- master
/ \
....--γ--C--D E--F <-- feature_branch (HEAD)
你将不可避免地从变基中得到的是:
C'-D' E'-F' <-- feature_branch (HEAD)
/ \ /
/___---B'
//
...--α--A------B <-- master
/ \
....--γ--C--D E--F [abandoned]
然后你可以强制移动master 指向B' 而不是B,这样你就有了:
C'-D' E'-F' <-- feature_branch (HEAD)
/ \ /
/___---B' <-- master
//
...--α--A------B
/ \
....--γ--C--D E--F [abandoned]
现在可以完全忽略B、γ、C 等的存在,并假设C' 是C。请注意,除非 α 和 γ 确实是同一个提交,否则提交 γ 已变得不可访问。
为了实现这个使用 git rebase,您需要有点新奇的-r 或--rebase-merges 选项:
git checkout feature_branch # if needed - you've drawn a detached HEAD
git rebase -i -r --onto master <hash-of-γ>
之后,您将需要从提交列表中删除 α 和 A 等提交,使其成为 pick-ed,因为这些提交目前都在 feature_branch 以及 master 上,通过合并提交B。 (请注意,-r 是 Git 2.18 中的新功能。-r 选项使用交互式机制来指示 Git 重新执行合并,这就是我们将在下面执行的操作。)
不过,总体而言,使用单独的 git cherry-pick 和 git merge 命令可能更容易实现这一点:
git checkout --detach <hash-of-A> # note: master~1 probably finds commit A
git cherry-pick <hash-of-C> # make C'
git cherry-pick <hash-of-D> # make D'
git merge --no-ff <hash-of-A> # make new merge B'
git branch -f master HEAD # forcibly update master now
git cherry-pick feature_branch~2 # make E'
git cherry-pick feature_branch~1 # make F'
git checkout -B feature_branch # forcibly move feature_branch and re-attach HEAD
如果master~1 确实识别提交A,您可以使用它来代替此处的每个文字哈希,在这种情况下,master^2^ 将识别提交C 和master^2 将识别提交D ,因此您可以使用它来代替这两个文字哈希 ID。