使用 `git rebase` 删除中间的提交

Use `git rebase` to remove a commit in the middle

我正在尝试撤消中间的提交,同时保持以下提交不变。在找到这些帖子之前,我认为这可能是不可能的:Post 1 & Post 2。 (最终目标可能是重复的,但我确实没有成功。对此我深表歉意。)

不幸的是,我仍然停留在如何正确使用 git rebase -i 上。我创建了一个示例 repo,如下所示:

commit cc2576365a9716bb9f96e195e599190d3c70fba0
Author: zzy
Date:   Sun Jul 17 14:30:53 2016 -0400
commit #3

commit 11d9f8fdc69be8b4530e4b70c9661b4e34287afe
Author: zzy
Date:   Sun Jul 17 14:30:36 2016 -0400
commit #2

commit 4770e08eb54d0d582bd4b391f2361a328b417cdf
Author: zzy
Date:   Sun Jul 17 14:29:58 2016 -0400
commit #1

每次提交都会在名为 a 的文件中添加一个新行(请参阅下面 a 的内容):

提交 #1 之后

1

提交 #2 之后

1
2

提交 #3 之后

1
2
3

现在我打算删除提交 #2,a 应该如下所示:

1
3

我尝试了命令 git rebase -i 11d9f8fdc69be8^ 并得到了文本文件:

pick 11d9f8f commit #2
pick cc25763 commit #3

我删除了第一行,只保留提交 #3 并退出了文件。但是我收到以下错误:

error: could not apply cc25763... commit #3

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
Could not apply cc2576365a9716bb9f96e195e599190d3c70fba0... commit #3

文件 a 变为:

1
<<<<<<< HEAD
=======
2
3
>>>>>>> cc25763... commit #3

我很困惑为什么 2 还在这里,为什么会有冲突。谁能帮我得到预期的结果?提前致谢!

基本上,由于提交 #2 和提交 #3 更改了同一文件中彼此非常接近的行,git 不太清楚如何 "replay"提交 #3 现在提交 #2 不再存在,所以你遇到了冲突。

在包含冲突的文件中,您会看到:

<<<<<<< HEAD
=======
2
3
>>>>>>> cc25763... commit #3

<<<<<<< HEAD======= 之间的 space 显示在创建提交 #2 或提交 #3 之前提交 #1 的该位置中包含的文件。在添加提交 #2 和提交 #3 之后,=======>>>>>>> cc25763... commit #3 之间的 space 包含提交 #3 中文件的该部分的内容。 Git 希望您使用此信息来手动决定提交 #3 的 new 版本应该包含哪些内容,因为您正在尝试在没有提交 #2 的情况下重播它。

在重播提交 #3 后,将文件的整个部分替换为您希望文件包含的内容。在这种情况下,您将替换:

<<<<<<< HEAD
=======
2
3
>>>>>>> cc25763... commit #3

与:

3

然后,运行 git add a 进行这些更改,git rebase --continue 继续变基。

请注意,只有在遇到冲突时才需要在变基期间执行此操作。对于更改不相关内容的提交(例如,如果提交 #2 和 #3 正在更改完全不同的文件,或同一文件的完全不同部分),git rebase 通常可以确定自动进行哪些更改,而您不会遇到冲突。