git - Git rebase 的 --merge 选项有什么作用?
问题描述
手册页git-rebase(1)说:
-m
--merge
使用合并策略来变基。[...]
--merge
但当然,如果不使用该选项,也可能会遇到“合并冲突” 。因此,在这种情况下,也必须有任何“合并策略”来处理这些冲突。
有什么区别可以--merge
选择变基。
这似乎是一些相当基本的东西:对于 a rebase --merge
,Git 将其工作文件存储在一个名为的文件夹中$GIT_DIR/rebase-merge
(就像它对交互式变基所做的那样)。如果--merge
未使用该选项(并且变基是非交互式的)该文件夹名为$GIT_DIR/rebase-apply
.
解决方案
一句话,-m
or--merge
是git rebase
为了确保 rebase 在git cherry-pick
内部使用。
-m
强制挑选樱桃的标志通常是多余的,但并不总是多余的。特别是,任何交互式变基总是使用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
不允许省略补丁部分。
git rebase
即使在使用-m
;时,这些空提交通常也会被忽略。您必须添加-k
以保留它们。要保存它们,git rebase
必须切换到cherry-pick 变体,如果它还没有这样做的话。
要传递-s
or-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
to B
、B
toC
和C
to的差异D
都在一个名为 的文件中处理lib-foo.ext
。但是在 commit 中F
,这个文件被重命名为lib/foo.ext
。A git format-patch
ofA..D
将显示要对文件进行的更改,由于没有文件,lib-foo.ext
这些更改都不会正确应用于提交。整个变基将失败。G
lib-foo.ext
但是,当识别出 commit时, A git cherry-pick
of commit将找到重命名并将-vs-更改应用于in commit的版本:B
HEAD
G
A
B
lib/foo.ext
G
B--C--D <-- topic
/
...--o--A--E--F--G <-- mainline
\
B' <-- HEAD [detached]
C
while HEAD
identify的下一个 cherry-pickB'
将发现B
-to - C
change tolibfoo.ext
应该应用于改名的lib/foo.ext
,并且最后一个cherry-pickD
将执行相同的操作,因此 rebase 将成功。
重命名检测代码很慢,所以一个没有重命名的变基,没有“空”提交,通过系统运行时可以运行得更快git format-patch | git am
。这是原始方法比樱桃挑选变体更好的唯一方法:在受限情况下它更快。(但是,只有当有很多重命名候选者时,速度才会提高,但是它们都不是实际的重命名,或者它们都不重要。)
(旁注:-3
参数,或者--3way
使用更长的拼写,告诉git am
将该标志传递给 each git apply
,如果需要,apply 将尝试使用index
diff 行中的 blob 哈希进行三向合并。在在某些情况下,这似乎足以处理重命名的文件 - 特别是如果 blob 哈希完全匹配。cherry-pick 方法进行完全重命名检测,它处理不精确的匹配;-3
不能这样做。另请参阅git 之间有什么区别如Jürgen 所说, cherry-pick 和 git format-patch | git am?。)
推荐阅读
- java - JedisException:资源作为损坏返回到池中
- bash - 无法在 xargs 中打印换行符
- c - 从文件中搜索字符串并使用 c 将其存储在结构中
- apache-spark - 洗牌后是否会自动触发缓存rdds?
- javascript - 简单的转译和 node_module 导入
- python-3.x - Pyspark 套接字超时错误。return self._sock.recv_into(b) socket.timeout: 超时
- javascript - 在 JavaScript 中将 1D 数组转换为 2D、3D 数组?
- java - Eclipse中使用字段生成的构造函数中的super关键字的目的是什么?
- ruby - 如何搜索两个或多个空格和指针 ruby
- rust - 如何使用 serde 反序列化 Prost 枚举?