libgit:在提交中获取文件的最快方法

时间:2015-12-08 13:23:16

标签: c++ git performance libgit2

我需要遍历存储库的提交并为每次提交获取受影响的文件。这是我目前巨大的性能瓶颈。

我有一个关于libgit函数的C ++包装器,但这段代码应该是可以理解的。

std::vector<std::string> Commit::getAffectedFiles() const {
  git_tree* tree = nullptr;
  git_tree* tree2 = nullptr;
  int error = git_commit_tree(&tree, get());
  throw_on_error(error);

  try {
    error = git_commit_tree(&tree2, parent(0).get());
  } catch (GitException e) {
    tree2 = nullptr; // probably initial commit
  }
  git_diff* diff = nullptr;
  git_diff_tree_to_tree(&diff, getRepo(), tree2, tree, 0);  

  std::vector<std::string> ret;
  git_diff_foreach(diff,
  [](const git_diff_delta* entry, float progress, void* payload) {
    std::string str = entry->old_file.path;
    ((std::vector<std::string>*)payload)->push_back(str);
    return 0;
  }, nullptr, nullptr, nullptr, &ret);
  git_tree_free(tree);
  git_tree_free(tree2);
  git_diff_free(diff);
  return ret; 
}

我只能希望我在这里做一些根本错误的事情。

例如

git log --stat > /dev/null

速度更快,并提供相同的信息。

perf按顺序报告git__strncmpgit_buf_rfind_nextgit_tree__parse的大部分用法。

我知道这是IO很重,但我没有看到一种简单的方法来减少这种情况或并行运行。

1 个答案:

答案 0 :(得分:1)

这相当于git在内部的作用,虽然git本身有更多的人在考虑它的性能,而libgit2并没有那么多的投资。

然而,最近一些补丁[0]被合并到libgit2的master分支中,这可以减少树解析时间的40%。我建议尝试一下,看看你得到了什么数字(补丁也应该很容易向后移植到早期版本)。

还要考虑到你的git版本很可能是在发布模式下编译的,默认情况下libgit2是在调试模式下构建的,所以如果你没有激活发布模式,请运行带有-DCMAKE_BUILD_TYPE=Release的cmake。这也显着加速了这些解析操作。

[0]特别是PR [{3}}和提交35080174f2