我一直在做一个git repo。在发布更改之前,我想删除一些提交-a023b43
,315424b
和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)
答案 0 :(得分:2)
问题是git rebase
使用了与git整体定义提交方式相矛盾的术语。提交是快照,但是rebase
将提交视为其父提交与其自身之间的补丁(一组更改)。
因此,如果您告诉rebase
“删除提交”,它认为您要撤消该提交补丁所应用的更改。
如果要删除一些快照,同时保持以后的快照相同,请告诉rebase
至squash
提交。用rebase
的术语来说,这意味着您正在将多个提交中的更改合并到最新的这些提交中。
答案 1 :(得分:1)
通过执行一系列提交并重新应用它们(可能在不同的“基础”对象上)来进行基础操作。它可以通过为每个提交创建补丁,然后重新应用它们,或者按顺序挑选它们来完成。
不管采用哪种机制,通过从基础指令列表中删除提交,您都要求将这些更改不包括在内。
想象一下,如果您有一些文件,并且在其初始版本中,它只有一行包含内容one
。想象一下,在下一次提交中,您将one
更改为two
。在随后的提交中,将two
到three
。然后从three
到four
,最后从four
到five
。因此,您现在有五个提交,每个提交都会更改此行。
想象一下,在每个提交中,您都给了它一条指示内容更改的消息,神奇地,提交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
的更改。第二个选择将从one
到two
的变化中进行选择,以此类推,直到最后一条指令将four
到five
的变化中进行选择。
如果您删除其中一些代码行,则可以:
pick 1111111 add one
pick 5555555 change four to five
您将有两个樱桃小点心。第一个将添加内容为one
的文件。第二个尝试将这些内容从four
更改为five
。
A,这些内容不是 four
。因此,您有冲突。
如果您的目标是从one
到five
而没有中间提交,那么您想squash
或将它们标记为fixup
提交。
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
。后续的更改将经过精心挑选,因此内容将从one
更改为two
。接下来的更改将被挑选出来,进一步更新文件,但是这些更改将被“压缩”到先前的提交中。这样,您将获得全部内容,但最终只会得到两次提交。
(如果您将它们标记为fixup
个提交,您将获得相同的内容,但是它们的提交消息不会包含在建议的提交消息中。
答案 2 :(得分:-1)
在这种情况下,我必须手工制作自己的提交
最终目标是创建一个如下所示的git日志:
6937ddd CV 2019.01
4c802c1初始提交
git rev-parse 70f72ca
git cat-file commit 6937ddd > commit.txt
parent
的{{1}}行更改为7b51754....
的输出1)
之所以起作用,是因为您已经用当前的提交链创建了所需的仓库状态。在提交对象中,回购状态由cat commit.txt | git hash-object -t commit --stdin -w
行定义,因此您在这里要做的就是显式定义哪个回购状态跟随另一个状态。