如何仅合并A到B的差异至C?Git局部合并技术问询
首先明确:你想要的是把B相对于A的所有变更(也就是A之后到B的所有提交的内容)合并到C分支,同时避开常规合并可能带来的、由A分支历史引发的大量冲突——这个需求完全合理,尤其是当C分支已经有大量独立修改的时候。
先直接给你结论:你设想的git merge A..B C命令是不可行的,因为git merge不接受提交范围作为参数,它只能针对具体的提交哈希、分支名或者标签来执行合并操作。不过我们有两种更合适的方案,完全符合你的需求:
方案一:生成并应用差异补丁(无提交历史,变更合并为单个提交)
这个方法会把A到B的所有变更打包成一个补丁文件,然后在C分支上应用,适合你不想引入A到B的提交历史,只想把变更合并成一个新提交的场景:
- 确保当前工作区干净,没有未提交的修改(可以用
git status检查) - 生成A到B的差异补丁:
这里的git diff A..B > ab-changes.patchA..B表示“B相对于A的所有差异”,如果你的提交是哈希值,直接替换成对应的长串即可。 - 切换到C分支:
git checkout C - 应用补丁到C分支:
git apply ab-changes.patch - 检查是否有冲突:如果补丁应用失败,Git会提示哪些文件有冲突,你需要手动打开这些文件解决冲突(冲突标记和常规合并冲突一致:
<<<<<<<、=======、>>>>>>>) - 解决完冲突后,标记文件为已解决:
git add <冲突文件名> - 最后提交变更:
git commit -m "Apply changes from commits A to B"
方案二:批量Cherry-Pick(保留A到B的提交历史)
虽然你提到不喜欢cherry-pick,但批量cherry-pick其实可以一次性处理A到B的所有提交,而且能保留每个提交的历史信息,适合需要追踪这些变更来源的场景:
切换到C分支:
git checkout C执行批量cherry-pick:
git cherry-pick A..B这个命令会把**A之后、B之前(包括B)**的所有提交依次应用到C分支上。如果遇到冲突,Git会暂停操作,你需要解决冲突后执行
git cherry-pick --continue继续,或者用git cherry-pick --abort取消整个操作。如果你想跳过某个有冲突的提交,可以用
git cherry-pick --skip。
为什么不推荐常规合并?
常规的git merge B(假设B是分支)会把B的整个历史合并到C,这会引入A分支的所有历史,而你在C分支的大量修改(比如删除文件、批量修改)很可能和A分支的历史变更产生冲突,这正是你想避免的情况——所以上面的两种方案更精准,只针对A到B的变更。
内容的提问来源于stack exchange,提问作者john s.

