如何使用Git Plumbing命令实现非快进合并(三方合并)?
Git底层命令实现三方合并的规范方式
你看到的.merge_file_XXXXX格式冲突标记是直接调用git merge-index git-merge-one-file -a的正常表现——底层命令不像上层git merge那样携带分支名、HEAD指向等上下文信息,只能用临时生成的文件名区分合并的两个版本。
如果想要得到和常规合并一致的冲突标记,同时规范完成三方合并,按照以下步骤操作:
1. 获取公共祖先提交
三方合并依赖三个版本:当前分支(ours)、目标分支(theirs)、两者的公共祖先(base)。先获取公共祖先的commit哈希:
BASE=$(git merge-base <branch1> <branch2>)
2. 加载三个版本的Tree到暂存区
使用git read-tree的三方合并模式,传入base、ours、theirs对应的tree对象(commit哈希可直接指代其tree),并通过-u参数同步更新工作区:
git read-tree -m -u $BASE <branch1> <branch2>
注:<branch1>是你要合并到的目标分支(ours),<branch2>是待合并的分支(theirs)。
3. 处理冲突并自定义标记
通过设置环境变量,给git-merge-one-file传递版本名称,让冲突标记显示为分支名而非临时文件名:
# 获取两个分支的tree哈希 OUR_TREE=$(git rev-parse <branch1>:) THEIR_TREE=$(git rev-parse <branch2>:) # 设置环境变量后执行合并 GITHEAD_$OUR_TREE="<branch1>" GITHEAD_$THEIR_TREE="<branch2>" git merge-index git-merge-one-file -a
此时冲突内容会显示为常规格式:
<<<<<<< <branch1> This is main branch ======= This is branch 1 >>>>>>> <branch2>
4. 完成合并(可选)
冲突解决后,可将暂存区的合并结果写入tree对象,再创建合并commit:
# 生成合并后的tree哈希 MERGED_TREE=$(git write-tree) # 创建合并commit(需自行填写提交信息) git commit -m "Merge branch '<branch2>' into <branch1>" -p $BASE <branch1> $MERGED_TREE
内容的提问来源于stack exchange,提问作者Maciej_Adamski
相关产品推荐
相关产品推荐

