Git rebase的--merge选项有什么作用?

时间:2019-04-29 09:56:04

标签: git git-rebase

手册页git-rebase(1)说:

  

-m
  --merge
  使用合并策略进行基础调整。 [...]

但是,当然,如果不使用--merge选项,也会遇到“合并冲突”。因此,在那种情况下,也必须有任何“合并策略”来处理这些冲突。

有什么区别使--merge选项成为基准。

这似乎是一个相当基本的东西:对于rebase --merge,Git将其工作文件存储在名为$GIT_DIR/rebase-merge的文件夹中(与交互式变基一样)。如果未使用--merge选项(并且rebase是非交互式的),则该文件夹名为$GIT_DIR/rebase-apply

1 个答案:

答案 0 :(得分:7)

在一句话中,-m--mergegit 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 ABBCC的差异都在文件中处理名为D。但是在提交lib-foo.ext中,此文件被重命名改为Flib/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] 的下一个樱桃选择将发现CHEAD变为{{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。)