对于像这样的存储库:
init---A---A2---...---[D---B---merge]---...---master
\ /
C---B2
B
和B2
发生冲突并在merge commit
解决。
现在我想加入提交A
和A2
到一个提交A
。我试过了
git rebase -i <commit id of init>
并改变
pick xxxxxxx A
pick xxxxxxx A2
...
至
pick xxxxxxx A
squash xxxxxxx A2
...
但是在应用B2时会出现冲突,我必须手动处理冲突,就像我在merge
中所做的那样。
实际上,整个提交树中有如此多的结构,甚至比方括号中的更复杂。因此,手动处理所有冲突是不现实的。
问题是,当我使用rebase
时,整个提交树将合并为一行,并且它不会通过应用提交merge
自动处理冲突。
那么我怎样才能只加入提交A和A2,但是在A2不变之后仍然保留所有提交结构,以便在操作之后存储库“看起来”相同?
为了进一步解释,在提交A
中,在测试文件中添加了一些敏感信息,并在提交A2
中将其删除。如果我不能永久删除这些信息,我就无法发布此项目。那么这种情况还有其他替代方案吗?
要加入(或称为“壁球”),您需要以交互方式进行rebase。如果要更改的提交是前两个,则可以从repo的根目录进行rebase。
这看起来有点像:
git rebase -i --root
pick hash X
squash hash Y
pick hash Z
-i
意味着你将以交互方式进行。 --root
意味着从回购的根源开始。
在初始命令之后,您将看到一个提交列表,其中前一个是第一个提交。要合并前两个提交,您可以简单地保留第一个提交(使用pick
关键字)并将前一个提交合并到其中(使用squash
关键字)。您还可以通过将pick
替换为reword
来编辑第一个提交消息。
完成此操作后,您应该将所有其他提交保留并确认。
更多信息可以在here找到
您还可以使用使用步骤将两个早期提交一起加入。
假设您要加入的提交位于master
分支上,并且提交历史记录为:
A---B---C---D---…---X master
要在提交B
(从C
提交到C
)之后保持提交历史记录的同时加入提交D
并提交X
,您可以使用以下命令:
git checkout -b temp <commit id for A>
git merge <commit id for C> --squash
git commit -m 'join B and C together'
现在提交历史将是(提交M
是壁球合并提交,加入提交B
和提交C
):
A---B---C---D---…---X master
\
M temp
然后你可以在提交C
之后重新定义以下提交:
git rebase --onto temp <commit id for C> master
git push -f origin master
git branch -D temp
现在master
分支上的提交历史将是(提交M
是提交连接提交B
并提交C
):
A---M---D'---…---X' master