git show显示合并提交差异原因及cherry-pick操作疑问
我以Linux内核源码为例,遇到了以下场景:
执行命令:$ git show df57721f9a63e8a1fb9b9b2e70de4aa4c7e0cd2e
该提交为merge commit,执行后会显示diff;
而执行命令:$ git show 535a265d7f0dd50d8c3a4f8b4f3a452d56bd160f
同样是merge commit,但执行后无diff显示。
针对这两个疑问,解答如下:
1. 为何两个merge commit的git show结果不同?
Git对merge commit的diff显示逻辑是:
- 如果merge commit是**快进合并(fast-forward)**生成的,它本质上只是移动了分支指针,没有产生任何新的修改内容——合并后的代码和其中一个父提交完全一致,所以
git show不会输出diff。 - 如果是非快进合并(比如合并时存在冲突需要手动解决,或者用
--no-ff强制生成独立的merge commit),这个merge commit会包含合并过程中的修改(比如冲突解决的内容、两个分支差异的整合),此时git show会显示该commit与父提交之间的diff。
你提到的第二个commit(535a265d7f...)属于快进合并的情况,而第一个commit(df57721f9...)是真正的非快进合并,所以两者的git show结果不同,确实和合并时的冲突解决(或是否有内容变更)直接相关。
2. 能否cherry-pick df57721f9a63e8a1fb9b9b2e70de4aa4c7e0cd2e对应的diff?
直接cherry-pick merge commit会要求指定-m选项选择父分支,这不符合你想要直接应用diff的需求。但可以通过以下方式提取并应用该merge commit的diff:
第一步,导出merge commit的diff到本地文件:
$ git show df57721f9a63e8a1fb9b9b2e70de4aa4c7e0cd2e > merge_diff.patch第二步,用patch命令将diff应用到当前分支:
$ patch -p1 < merge_diff.patch
这样就能把该merge commit中包含的修改(比如冲突解决的内容、分支整合的变更)直接应用到当前工作区,达到类似“cherry-pick diff”的效果。
内容的提问来源于stack exchange,提问作者1010101

