手册页git-rebase(1)说:
-m
--merge
使用合并策略进行基础调整。 [...]
但是,当然,如果不使用--merge
选项,也会遇到“合并冲突”。因此,在那种情况下,也必须有任何“合并策略”来处理这些冲突。
有什么区别使--merge
选项成为基准。
这似乎是一个相当基本的东西:对于rebase --merge
,Git将其工作文件存储在名为$GIT_DIR/rebase-merge
的文件夹中(与交互式变基一样)。如果未使用--merge
选项(并且rebase是非交互式的),则该文件夹名为$GIT_DIR/rebase-apply
。
答案 0 :(得分:7)
在一句话中,-m
或--merge
对git rebase
的作用是确保变基在内部使用git cherry-pick
。
强制{-{1}}标志来强制执行摘樱桃操作通常(但并非总是)是多余的。尤其是,任何 interactive 换库始终始终使用Cherry-pick。与joanis noted in a comment一样,指定任何-m
或-s
选项也将强制使用cherry-pick。如下所述,-X
也是如此。
Rebase在Git中有很长的历史:第一个rebase操作是通过将每个要重新构建的提交格式化为补丁,然后将补丁应用于其他提交来完成的。就是说,-k
最初只是:
git rebase
(除了参数处理,所有错误检查以及branch=$(git symbolic-ref --short HEAD)
target=$(git rev-parse ${onto:-$upstream})
git format-patch $upstream..HEAD > $temp_file
git checkout $target
git am -3 $temp_file
git checkout -B $branch HEAD
可能因错误而停止,需要手工修复和git am
的事实;此外,上述脚本是我简化的-可读性版本,可能与原始脚本不太相似。
这种变基可以很好地处理大多数情况。它不能很好地处理的最常见情况是在某些文件重命名上重新设置基准。它还不允许复制“空”提交(即补丁为空的提交),因为不允许git rebase --continue
省略补丁部分。
git format-patch
通常会忽略这些空的提交,即使使用git rebase
也是如此;您必须添加-m
才能保留它们。要保留它们,-k
必须切换到cherry-pick变体(如果尚未这样做)。
要传递git rebase
或-s
参数,rebase必须调用-X
而不是git cherry-pick
,因此这些标志中的任何一个都还需要cherry-pick变体。
使用git am
不会进行任何重命名检测。因此,如果您要复制的提交流都应针对git format-patch
应用重命名检测,则HEAD
标志非常重要。作为一个具体示例,请考虑以下一系列提交:
-m
假定从 B--C--D <-- topic
/
...--o--A--E--F--G <-- mainline
到A
,B
到B
和C
到C
的差异都在文件中处理名为D
。但是在提交lib-foo.ext
中,此文件被重命名改为F
。 lib/foo.ext
中的git format-patch
将显示要对文件A..D
进行的更改,因为没有lib-foo.ext
文件,没有一个更改将正确地应用于提交G
。整个重新部署将失败。
当lib-foo.ext
标识提交git cherry-pick
时,提交B
的{{1}}将找到重命名并应用HEAD
-vs-{{1 }}在提交G
中更改为A
的版本:
B
在lib/foo.ext
标识G
的同时, B--C--D <-- topic
/
...--o--A--E--F--G <-- mainline
\
B' <-- HEAD [detached]
的下一个樱桃选择将发现C
到HEAD
变为{{1 }}应该应用于重命名的B'
,并且B
的最后一个选择将执行相同的操作,以便重新设置成功。
重命名检测代码很慢,因此具有 no 进行重命名并且没有保留“空”承诺的重新构建可以通过C
系统运行时更快。那是原始方法比Cherry-pick变体更好的唯一方法:在受约束的情况下它更快。 (但是,只有在有很多重命名候选时,速度才会提高,但是它们都不是实际的重命名,或者都不重要。)
(注意:libfoo.ext
参数或lib/foo.ext
使用更长的拼写,告诉D
将该标志传递给每个git format-patch | git am
,在哪里应用尝试使用diff中-3
行中的blob散列进行三向合并。在某些情况下,看起来 might 足以处理重命名的文件-尤其是如果Blob哈希值完全匹配。cherry-pick方法执行完全重命名检测,该处理会处理不精确的匹配; --3way
无法做到这一点。另请参阅What is the difference between git cherry-pick and git format-patch | git am?,也称为Jürgen noted。)>