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

问题描述 投票:5回答:1

手册页git-rebase(1)说:

-m - 合并 使用合并策略进行rebase。 [...]

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

--merge选项与rebase有什么区别。

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

git git-rebase
1个回答
8
投票

在一句话中,-m--mergegit rebase做的是确保rebase在内部使用git cherry-pick

强迫樱桃挑选的-m旗帜经常(但并非总是)多余。特别是,任何交互式rebase总是使用cherry-pick。作为joanis noted in a comment,指定任何-s-X选项也强制使用樱桃选择。 -k也是如此,如下所述。

Long (or at least longer)

Rebase在Git中有着悠久的历史:第一个rebase操作是通过将每个提交格式化为一个补丁,然后将补丁应用于其他一些提交来完成的。也就是说,最初,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;另外,上面的脚本是我的可读性降低版本,可能与原始版本不同脚本很多)。

这种rebase很好地处理了大多数情况。它处理不好的最常见情况涉及跨某些文件重命名的变基。它也不能复制其补丁为空的“空”提交 - 即 - 因为git format-patch不允许省略补丁部分。

即使使用git rebase-m通常也会省略这些空提交;你必须添加-k来保存它们。为了保护它们,git rebase必须切换到樱桃挑选变体,如果还没有这样做的话。

要传递-s-X参数,rebase必须调用git cherry-pick而不是git am,因此任何这些标志也需要cherry-pick变体。

使用git format-patch永远不会进行任何重命名检测。因此,如果你正在复制的提交流都应该对HEAD进行重命名检测,那么-m标志非常重要。有关具体示例,请考虑以下一系列提交:

          B--C--D   <-- topic
         /
...--o--A--E--F--G   <-- mainline

假设从ABBCCD的差异都在一个名为lib-foo.ext的文件中处理。但是在提交F中,此文件被重命名为lib/foo.extgit format-patchA..D将显示对文件lib-foo.ext所做的更改,由于没有G文件,因此没有一个将正确应用于提交lib-foo.ext。整个rebase将失败。

git cherry-pick识别提交B时,提交HEADG,然而,将找到重命名并将A-vs-B更改应用于提交lib/foo.ext中的G版本:

          B--C--D   <-- topic
         /
...--o--A--E--F--G   <-- mainline
                  \
                   B'   <-- HEAD [detached]

C的下一个樱桃选择,而HEAD识别B',将发现BC更改为libfoo.ext应该应用于重命名的lib/foo.ext,而D的最后一个樱桃选择将做同样的事情,以便rebase将会成功。

重命名检测代码很慢,因此没有重命名的rebase,并且没有“空”提交保留,通过git format-patch | git am系统运行时可以运行得更快。这是关于原始方法比樱桃挑选变体更好的唯一方法:它在受约束的情况下更快。 (但是,只有在有大量重命名候选者时才会出现速度提升,但要么它们都不是实际重命名,要么都不重要。)

(旁注:-3参数,或--3way使用更长的拼写,告诉git am将该标志传递给每个git apply,其中apply将尝试在需要时进行三向合并,使用index线中的blob哈希值在某些条件下,似乎这可能足以处理重命名的文件 - 特别是如果blob哈希完全匹配。樱桃挑选方法执行完全重命名检测,处理不精确的匹配; -3不能这样做。参见What is the difference between git cherry-pick and git format-patch | git am?Jürgen noted。)

© www.soinside.com 2019 - 2024. All rights reserved.