我有一个应用程序,它通过运行以下命令来生成一个进程,以便在git存储库中的特定提交中查找特定正则表达式的出现:
git grep -G pattern revision
这很好用,但问题是我在循环中这样做,这非常慢。我在Linux上分析了代码,单独调用__libc_fork
占用了94%的运行时间。
显然,我想避免这种不必要的开销。要做一些其他的git操作,我已经在我的应用程序中使用 libgit2 ,但是我没有看到像git grep
一样执行正则表达式搜索的便捷方法。我可以想象手动浏览与提交相关的所有文件并执行搜索,但我希望有一个更优雅的解决方案,最多几行。
我错过了相关的 libgit2 API吗?有没有人知道使用 libgit2 搜索模式的快捷方法?
编辑只是为了澄清:在我的循环中,修订是固定的,但模式会发生变化。
答案 0 :(得分:0)
libgit2没有git grep
等价物,因为它远不及基本的Git操作。这是非常高的级别,实际有趣的工作(高效的grep)与Git无关,因此libgit2将是放置该代码的不好的地方。
由于您看到的问题归结为分叉比其他任何东西都要昂贵,我认为有两种方法可以避免这种情况。一种方法是使用git cat-file
的{{1}}选项为其提供要显示的对象列表,您可以从中获取,例如来自--batch
喜欢
ls-tree
在每个文件的开头生成一个机器可读输出,其中git ls-tree -r ${revision} | cut -f 1 | cut -d ' ' -f 3 | git cat-file --batch
三元组(使用您自己的代码从流中提取ID可能更容易/更便宜地替换$id $type $len
来自cut
)。或者您可以使用libgit2来遍历树并以递归方式从树中获取所有blob,这最终会以稍微不同的方式获取相同的信息。
然后你可以使用某种形式的grep来运行这些缓冲区。您最喜欢的编程语言可能有一个pcre或绑定到该库的实现,您可以提供这些文件。
您应该能够一次一个地提供它们,无论您选择哪种提取方法,只需通过ls-tree
一次通过每个对象之前的三元组读取一个。{1}}。