如何在某一条目不存在时调用git_merge_file_from_index函数?
问题描述
函数git_merge_file_from_index接收三个git_index_entry*类型的参数:ancestor、ours和theirs。但如果其中任一参数为null,函数就会崩溃——可这种参数为null的场景其实是合理的:
比如存在一个基础提交base,以及两个从它派生的子提交foo和bar。如果某个文件在base中存在,提交foo删除了该文件,而提交bar修改了它,那么将bar合并到foo时,就会出现ours对应的git_index_entry不存在的冲突场景。
这种情况下,我们该如何获取合并结果?
解决方案
针对这种参数为null的合法合并场景,不能直接调用git_merge_file_from_index,需要先手动识别场景,再通过Git的底层API或自定义逻辑处理:
先明确缺失参数对应的操作
先判断哪个参数为null,对应不同的分支操作:ours为null:当前分支(foo)删除了目标文件,对方分支(bar)修改了该文件theirs为null:对方分支删除文件,当前分支修改了该文件ancestor为null:文件属于其中一个分支的新增内容
分场景处理合并结果
- 当前分支删文件,对方分支改文件
这是典型的删除-修改冲突,Git原生逻辑会标记为手动冲突,你可以根据需求选择:- 保留对方修改:直接将
theirs对应的文件内容作为合并结果,同时将文件添加回当前索引 - 保留删除操作:忽略
theirs的修改,维持文件删除状态 - 生成冲突标记内容:模拟Git默认的冲突提示格式,比如:
<<<<<<< HEAD (文件已被删除) ======= [bar分支的文件内容] >>>>>>> bar
- 保留对方修改:直接将
- 对方分支删文件,当前分支改文件
逻辑与上述相反,要么保留当前分支的修改,要么接受对方的删除操作,或者生成冲突内容。
- 当前分支删文件,对方分支改文件
用
git_merge_file替代git_merge_file_from_index
如果你不想手动构造内容,可以使用git_merge_file函数——它接受git_merge_file_input结构体,允许传入空输入(对应文件不存在的情况),不会因参数为null崩溃。示例代码大致如下:git_merge_file_input ancestor_input = GIT_MERGE_FILE_INPUT_INIT; git_merge_file_input ours_input = GIT_MERGE_FILE_INPUT_INIT; git_merge_file_input theirs_input = GIT_MERGE_FILE_INPUT_INIT; // 填充存在的索引项内容 if (ancestor != NULL) { git_blob *blob; git_blob_lookup(&blob, repo, &ancestor->id); git_merge_file_input_from_blob(&ancestor_input, blob); git_blob_free(blob); } // 同理处理ours和theirs,不存在则保持INIT空输入状态 git_merge_file_result *result; git_merge_file(&result, &ancestor_input, &ours_input, &theirs_input, NULL); // 处理合并结果 git_merge_file_result_free(result);这个函数会自动处理某一方文件不存在的场景,生成符合Git合并规则的结果(冲突标记或对应操作的保留)。
内容的提问来源于stack exchange,提问作者Mike Jerred
相关产品推荐
相关产品推荐

