У меня есть приложение, которое порождает процесс, чтобы найти экземпляры определенного регулярного выражения в определенном коммите в репозитории git, выполнив:
git grep -G pattern revision
Это работает просто отлично, но проблема в том, что я делаю это в цикле, и это очень медленно. Я профилировал код на Linux и призыв к __libc_fork
один занимает 94% времени выполнения.
Очевидно, я бы хотел избежать этих ненужных накладных расходов. Чтобы сделать некоторые другие операции с Git, я уже использую libgit2 в моем приложении, но я не вижу удобного способа выполнить поиск по регулярному выражению, как я могу с git grep
, Я могу представить, как вручную просматривал все файлы, связанные с фиксацией, и выполнял поиск, но я надеялся на более элегантное решение, вплоть до нескольких строк.
Я пропускаю соответствующий libgit2 API? Кто-нибудь знает быстрый способ поиска шаблона с помощью libgit2?
РЕДАКТИРОВАТЬ Просто чтобы уточнить: в моем цикле ревизия исправлена, но шаблон меняется.
libgit2 не имеет git grep
эквивалентно, так как это не близко к основной операции Git. Это очень высокий уровень, и настоящая интересная работа (эффективный grep) не имеет ничего общего с Git, поэтому libgit2 будет плохим местом для размещения этого кода.
Поскольку проблема, которую вы видите, заключается в том, что раздвоение обходится дороже, чем что-либо еще, я вижу два способа избежать этого. Одним из них является использование git cat-file
«s --batch
возможность подать ему список объектов для показа, который вы можете получить, например. от ls-tree
лайк
git ls-tree -r ${revision} | cut -f 1 | cut -d ' ' -f 3 | git cat-file --batch
который производит машиночитаемый вывод с $id $type $len
триплет в начале каждого файла (может быть проще / дешевле заменить те cut
с вашим собственным кодом, который извлекает идентификаторы из потока, поступающего из ls-tree
). Или вы можете использовать libgit2, чтобы пройти по дереву и рекурсивно выхватить все капли с деревьев, что в итоге даст вам ту же информацию немного другим способом.
Затем вы можете использовать некоторую форму grep для запуска этих буферов. Ваш любимый язык программирования, вероятно, имеет реализацию pcre или привязок к той библиотеке, которую вы можете передать этим файлам.
Вы должны иметь возможность кормить их по одному, независимо от того, какой метод извлечения вы выберете, только читая из cat-file
по одному через те тройки, которые предшествуют каждому объекту.
Других решений пока нет …