首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有可能在diff3合并冲突或libgit2中的复合差异中获得行的来源?

是否有可能在diff3合并冲突或libgit2中的复合差异中获得行的来源?
EN

Stack Overflow用户
提问于 2014-09-15 13:54:18
回答 1查看 189关注 0票数 2

我知道如何生成包含diff3的文件:只需复制跟随diff3试验即可。

假设diff3包含:

代码语言:javascript
复制
context1
<<<<<<< master
ours
||||||| base
base
=======
theirs
>>>>>>> topic
context2

我想让它得到以下地图:

代码语言:javascript
复制
line        origin
-------------------
context1 -> CONTEXT
ours     -> OURS
base     -> BASE
theirs   -> THEIRS
context2 -> CONTEXT

可能在回调循环中,就像对打印上的diff行那样,它将一个git_diff_line传递给回调,回调包含origin属性GIT_DIFF_LINE_CONTEXT

当然,我可以解析文件并查找冲突标记<<<,但是如果文件本身包含标记,则会导致模糊,所以我不想这样做。

或者,如果我可以获得一个复合diff (合并冲突解决过程中的默认diff格式)为:

代码语言:javascript
复制
  context1
++<<<<<<< master
 +ours
++||||||| base
++base
++=======
+ theirs
++>>>>>>> topic
  context2

这也是一种可能的解决方案,因为由于+和空格字符,在这种格式中不可能有歧义。但是,这样做就不太好了,因为我仍然需要对libgit2已经解析过的信息进行一些手动解析,因为它最初是用来创建文件的。

我想这样做是因为我正在为GitLab:https://github.com/gitlabhq/gitlabhq/pull/7345实现一个合并解析工具

编辑

因为这似乎是不可能的,所以我提出了一个建议,它的接口是:https://github.com/libgit2/libgit2/issues/2568

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-15 15:35:05

不,libgit2没有提供您可以使用的任意三向diff/merge工具:虽然它在内部使用diff/merge工具来合并文件,但它没有为调用者提供获取关于合并数据的大量信息的方法。

相反,您应该使用您选择的任何diff/merge工具。(git和libgit2使用xdiff库,尽管您可以使用任何您想使用的库。)

很容易从存储库repo中某个名为repo的文件的索引中获取冲突数据,然后您可以将其提供给您的工具:

代码语言:javascript
复制
git_index *index;
git_odb *odb;
git_index_entry *ancestor, *ours, *theirs;
git_odb_object *ancestor_file = NULL, *ours_file = NULL, *theirs_file = NULL;
const void *ancestor_data = NULL, *ours_data = NULL, *theirs_data = NULL;
size_t ancestor_size = 0, ours_size = 0, theirs_size = 0;

git_repository_index(&index, repo);
git_repository_odb(&odb, repo);

ancestor = git_index_get_bypath(index, filename, 1);
ours = git_index_get_bypath(index, filename, 2);
theirs = git_index_get_bypath(index, filename, 3);

if (ancestor) {
  git_odb_read(&ancestor_file, odb, &ancestor->id);

  ancestor_data = git_odb_object_data(ancestor_file);
  ancestor_size = git_odb_object_size(ancestor_file);
}

if (ours) {
  git_odb_read(&ours_file, odb, &ours->id);

  ours_data = git_odb_object_data(ours_file);
  ours_size = git_odb_object_size(ours_file);
}

if (theirs) {
  git_odb_read(&theirs_file, odb, &theirs->id);

  theirs_data = git_odb_object_data(theirs_file);
  theirs_size = git_odb_object_size(theirs_file);
}

/*
 * At this point, you can feed `ancestor_data`, `ours_data` and
 * `theirs_data` in to your diff/merge tool.  They are byte arrays
 * containing the contents of the file and are `ancestor_size`,
 * `ours_size` and `theirs_size` bytes long, respectively.
 *
 * If one any was `NULL`, then the conflict does not include
 * that side of the file, in the case of an add/add conflict or
 * if one side was deleted.
 */

git_odb_object_free(ancestor_file);
git_odb_object_free(ours_file);
git_odb_object_free(theirs_file);

(请注意,此代码未经测试,请注意缺少错误检查。)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25849742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档