[英]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
或--merge
对git 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
不允许省略补丁部分。
即使使用-m
, git 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
假设从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
文件。 整个rebase将失败。
当HEAD
识别提交G
时,提交B
git cherry-pick
,但是,会找到重命名并将A
-vs- B
更改应用于提交G
的lib/foo.ext
版本:
B--C--D <-- topic
/
...--o--A--E--F--G <-- mainline
\
B' <-- HEAD [detached]
下一个选择C
而HEAD
标识B'
,将发现对libfoo.ext
的B
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.