首页 > 解决方案 > 为什么从 git rebase 丢弃的提交会导致合并冲突?

问题描述

我的问题

我一直在做一个 git repo。在发布我的更改之前,我想删除一些提交 -a023b43315424b-7b51754因为它们不反映任何有意义的更改。唯一重要的时间点是第一次 ( 70f72ca) 和最后一次 ( 6937ddd) 提交。

我试过什么

git rebase -i 4c802c1

我选择了:

pick 70f72ca Remove repetitions from Makefile
d a023b43 Separate target for image conversion
d 315424b Remove image conversion (#1)
d 7b51754 Fix Makefile
pick 6937ddd CV 2019.01

最终目标是有一个看起来像这样的 git 日志:

6937ddd CV 2019.01
4c802c1 Initial commit

什么没有奏效

Auto-merging src/Adam_Matan.tex
CONFLICT (content): Merge conflict in src/Adam_Matan.tex
error: could not apply 6937ddd... CV 2019.01

Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

Could not apply 6937ddd... CV 2019.01

据我了解,这两个提交只是我工作目录的快照。我想要两个快照-原始提交和CV 2019.01一个。我不想以任何方式合并或组合它们。为什么我会收到合并冲突消息?

我的问题

如何从分支中删除所有中间提交,只保留第一个和最后一个提交?

更新

挤压也会产生合并冲突:

git rebase -i 4c802c1
Auto-merging Makefile
CONFLICT (content): Merge conflict in Makefile
error: could not apply 315424b... Remove image conversion (#1)

标签: gitrebasemerge-conflict-resolution

解决方案


Rebase 通过进行一系列提交并重新应用它们来执行操作,可能是在不同的“基础”对象上。它通过为每个提交创建一个补丁并重新应用它们,或者通过按顺序挑选它们来实现。

无论采用何种机制,通过从 rebase 指令列表中删除提交,您已要求包括这些更改。

想象一下,如果您有一些文件,并且在其初始修订版中,它只有一行内容one。想象一下,在下一次提交中,您更改onetwo. 在随后的提交中,twothree. 然后threefour,最后fourfive。所以你现在有五次提交,每一次都改变了这一行。

想象一下,在每次提交中,您都给了它一条指示内容更改的消息,并且神奇地提交 ID(哈希)也反映了内容。运行rebase -i --root会给你这个脚本:

pick 1111111 add one
pick 2222222 change one to two
pick 3333333 change two to three
pick 4444444 change three to four
pick 5555555 change four to five

换句话说,第一次提交选择从无到one. 第二个将挑选从oneto的变化two等,直到最后一条指令挑选从fourto的变化five

如果您删除其中一些行,则为您提供:

pick 1111111 add one
pick 5555555 change four to five

你将有两个樱桃采摘。第一个将添加一个包含内容的文件one。第二个将尝试将这些内容从 更改fourfive

唉,那些内容不是 four。因此,您有冲突。

如果您的目标是在没有中间提交的情况下从oneto 开始,那么您希望将它们标记为提交或将它们标记为提交。fivesquashfixup

pick 1111111 add one
pick 2222222 change one to two
squash 3333333 change two to three
squash 4444444 change three to four
squash 5555555 change four to five

在这种情况下,第一个更改将被精心挑选,因此one将创建文件。随后的更改将被精心挑选,因此内容将从 更改onetwo。随后的更改将被精心挑选,进一步更新文件,但这些更改将被“压缩”到先前的提交中。因此,您将获得完整的内容,但最终只会提交两次。

(如果您将它们标记为fixup提交,您将获得相同的内容,但它们的提交消息不会包含在您建议的提交消息中。


推荐阅读