繁体   English   中英

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

[英]What does the --merge option of Git rebase do?

手册页git-rebase(1)说:

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

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

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

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

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

强制樱桃挑选的-m标志通常但并不总是多余的。 特别是,任何交互式 rebase总是使用cherry-pick。 正如joanis在评论中指出的那样 ,指定任何-s-X选项也会强制使用cherry-pick。 -k也是如此,如下所述。

长(或至少更长)

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不允许省略补丁部分。

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

要传递-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.ext 一个git format-patchA..D来进行将显示更改文件lib-foo.ext ,其中没有将正确适用于犯下G因为没有lib-foo.ext文件。 整个rebase将失败。

HEAD识别提交G时,提交B git cherry-pick ,但是,会找到重命名并将A -vs- B更改应用于提交Glib/foo.ext版本:

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

下一个选择CHEAD标识B' ,将发现对libfoo.extB C to libfoo.ext C更改应该应用于重命名的lib/foo.ext ,而D的最后一个选择将会执行同样的,这样才能成功。

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

(旁注: -3参数,或--3way使用更长的拼写,告诉git am将该标志传递给每个git apply ,其中apply将尝试在需要时使用blob进行三向合并差异中的index行中的哈希值。在某些情况下,似乎这可能足以处理重命名的文件 - 特别是如果blob哈希完全匹配.chown-pick方法执行完全重命名检测,处理不精确的匹配; -3不能那样做。另见git cherry-pick和git format-patch | git am?有什么区别 ,正如Jürgen所说 。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM