我正在尝试用另一个提交很少的分支来重定一个分支。 虽然提交包括合并提交,但我能够使用以下命令成功地将其变基git rebase -i -r -m <base_branch>
但是,当我尝试使用"reword
"修改某些提交消息时,我看到了合并冲突。
我尝试git rebase -i -r -m <base_branch>
命令并更改了一些提交以改写而不是选择,在此之后出现合并冲突。
使用的命令:git rebase -i -r -m <base_branch>
我希望成功的变基,但存在冲突。
这可能是因为原始合并也有冲突。 (如果没有访问存储库及其提交,我无法证明情况确实如此。
你所看到的是这样一个事实的副作用,有时,git rebase
可以避免部分或全部副本,当它可以并且确实避免所有副本时,它最终什么都不做。 什么都不做意味着没有合并提交,但是"复制"之前有合并冲突的合并意味着您再次看到相同的合并冲突。
您可以使用git rerere
(以及rerere-train
脚本,也许:请参阅更智能的变基避免冗余工作?
长
请记住,git rebase
通过复制提交来工作。 简单的交互式变基首先列出所有要复制的提交,对每个此类提交使用pick
命令。 不过,这种简单的变基丢弃合并。 添加--rebase-merges
(或-r
)告诉它:保留合并,以及提交的原始排列。但是整个概念存在一个缺陷:虽然可以复制非合并提交,但不可能复制合并提交。
git rebase -r
(及其年长、更穷的git rebase -p
表亲)所做的是在必要时重新执行合并,因为他们无法复制合并。 也就是说,在将一些旧提交复制到新提交之后,使用新的和不同的哈希 ID,它们到了"复制"合并的时候了,相反,它们只是直接运行git merge
。
例如,给定:
C--D
/
A--B G--H <-- source (HEAD)
/ /
/ E--F
/
...--o--o--*--o--o <-- target
命令行请求git rebase -r target
将生成一系列pick
、label
、reset
和merge
命令来复制A
、B
、C
、D
、E
和F
;然后将the copies of
D合并and
F; then copy
Gand
H',得到:
C--D
/
A--B G--H <-- [abandoned]
/ /
/ E--F
/
...--o--o--*--o--o <-- target
C'-D'
/
A'-B' G'-H' <-- source (HEAD)
/
E'-F'
其中提交A'
是A
的副本,B'
是B
的副本,依此类推。
但是,无论是否使用-r
选项,请考虑以以下内容开头的变基操作:
...--I--J <-- target
K--L <-- source (HEAD)
您现在要求 Git 通过git rebase
将提交K
复制到一个新的和改进的K
,该与K
完全相同,只是它出现在J
之后,而不是在J
之后。 然后你告诉 Git 复制L
这样它就不会在K
之后,而是在K
的新副本之后。
Git 意识到J
之后的现有K
副本已经紧随J
之后。 因此,它需要制作的"副本"已经存在:git rebase
只是直接重用K
。 现在它必须复制L
才能在K
之后,但是看:L
已经在K
之后了,所以 Git 只是直接重用L
。 结果是没有任何变化。 (如果出于某种原因(并且有一些原因),您真的希望Git 无论如何都复制K
,您可以使用--force-rebase
或--no-ff
或-f
,所有这些都做同样的事情。
如果您运行相同的变基,请确保使用交互模式,并在K
上使用reword
,现在 Git 确实必须将K
复制到类似于K
但具有不同提交消息的新K'
。 因此,Git现在确实必须复制L
,以便它出现在带有新消息的新K'
之后。 结果是:
K'-L' <-- source (HEAD)
/
...--I--J <-- target
K--L [abandoned]
对于像这样的简单线性情况,变基总是顺利进行,但是当您将-r
添加到组合中时,为了强制 Git "复制"(即重新执行)合并,如果原始合并有冲突,则新的合并也会发生冲突。