Перейти к основному содержимому

tgrep — сверхбыстрый поиск по коду от Microsoft

·857 слов·5 минут·
Оглавление
logo

Вводишь поисковый запрос через grep или ripgrep в большом монорепозитории или проекте на сотни тысяч файлов, и терминал подвисает на 10–30 секунд?

В Microsoft тоже столкнулись с этой же проблемой и создали tgrep — утилиту на Rust с триграммной индексацией и клиент-серверной архитектурой. Сейчас tgrep уже интегрирован в GitHub Copilot CLI и доступен в open source под свободной лицензией MIT.

В этой статье разберем, как он устроен, как установить его на macOS и как внедрить в повседневную работу.

В чем магия tgrep и почему он быстрее ripgrep?
#

Привычные утилиты (grep, ripgrep, ag) работают линейно: на каждый поисковый запрос они заново обходят дерево файлов и читают их содержимое с диска (сложность $O(\text{объем байт})$). Даже при параллельном чтении и быстром SSD на миллионах строк кода это занимает ощутимое время.

tgrep использует иной подход:

  1. Триграммный индекс: во время предварительной индексации файл разбивается на 3-символьные последовательности (триграммы). Из них строится компактная инвертированная таблица поиска.
  2. Мгновенная фильтрация: при поиске регулярное выражение парсится на литеральные фрагменты и триграммы. tgrep мгновенно исключает подавляющую часть файлов, где совпадения гарантированно быть не может, и запускает полный regex-поиск только по оставшимся кандидатам.
  3. Клиент-серверный режим: демон tgrep serve держит индекс в памяти и слушает изменения файловой системы через нативный механизм macOS — FSEvents. Любые правки мгновенно попадают в in-memory оверлей (LiveIndex). Поисковый клиент tgrep связывается с сервером по локальному TCP (JSON-RPC) и получает результат за миллисекунды.

Бенчмарки на macOS (Apple Silicon arm64)
#

В замерах разработчиков Microsoft на реальных кодовых базах:

РепозиторийФайловripgreptgrepУскорение
gecko-dev (Firefox)388 00033.4 с0.64 с~52x
chromium504 00041.8 с2.64 с~16x
linux kernel96 0005.4 с0.26 с~21x

Установка на macOS
#

Способ 1: Homebrew (рекомендуется)
#

tgrep уже добавлен в официальный репозиторий Homebrew core, поэтому ставится одной командой:

brew install tgrep

Проверяем установку:

tgrep --version

Способ 2: Готовые бинарники с GitHub Releases
#

Если вы не пользуетесь Homebrew или хотите скачать релиз напрямую через GitHub CLI:

Для Apple Silicon (M1/M2/M3/M4):

gh release download --repo microsoft/tgrep -p '*aarch64-apple-darwin*' -D /tmp/tgrep-dl
sudo tar xzf /tmp/tgrep-dl/tgrep-*-aarch64-apple-darwin.tar.gz -C /usr/local/bin

Для процессоров Intel:

gh release download --repo microsoft/tgrep -p '*x86_64-apple-darwin*' -D /tmp/tgrep-dl
sudo tar xzf /tmp/tgrep-dl/tgrep-*-x86_64-apple-darwin.tar.gz -C /usr/local/bin

Рабочий процесс
#

1. Построение индекса (tgrep index)
#

Перейдите в корень вашего проекта и постройте индекс:

cd ~/my-big-project
tgrep index .

Индекс сохраняется в локальную директорию .tgrep/.

Обязательно добавьте .tgrep в ваш .gitignore или глобальный ~/.gitignore, чтобы не коммитить файлы индекса в репозиторий:

echo ".tgrep/" >> .gitignore

2. Запуск фонового сервера (tgrep serve)
#

Чтобы не перестраивать индекс вручную после каждой правки кода, запустите сервер наблюдения:

tgrep serve . &

Сервер использует Apple FSEvents, потребляет минимум ресурсов в фоне и поддерживает актуальность индекса при любых изменениях файлов.

Проверить состояние сервера можно командой:

tgrep status .

Вывод покажет PID процесса, открытый TCP-порт, количество проиндексированных файлов, число триграмм и статус наблюдателя (Watcher: active).

3. Поиск по коду
#

Теперь можно выполнять поисковые запросы. Клиент автоматически обнаружит запущенный сервер и выдаст ответ почти мгновенно:

tgrep "handle_request" .

Полезные флаги и примеры (совместимость с ripgrep)
#

Интерфейс командной строки tgrep намеренно повторяет синтаксис ripgrep (rg), поэтому переучиваться не придется:

Поиск точной подстроки без регулярных выражений (-F)
#

tgrep -F "Map<String, List<User>>" .

Поиск слова целиком (-w) и без учета регистра (-i или -S)
#

tgrep -w "config" . -i
# -S / --smart-case: регистронезависимый поиск, если паттерн в нижнем регистре
tgrep -S "myfunction" .

Ограничение типами файлов (-t) или глоб-паттернами (-g)
#

# Только Rust файлы
tgrep "struct Config" . -t rust

# Только TypeScript и JavaScript
tgrep "export const" . -g "*.{ts,tsx,js}"

Список всех поддерживаемых типов файлов можно посмотреть через:

tgrep --type-list

Вывод контекста вокруг совпадения
#

tgrep -C 3 "panic\!" .        # 3 строки до и после
tgrep -A 2 -B 1 "throw new" . # 2 строки после, 1 строка до

Только имена файлов (-l) или подсчет количества (-c)
#

tgrep -l "TODO" .
tgrep -c "deprecated" .

Вывод в формате JSON или Vim
#

# JSON-стрим (полностью совместим со схемой ripgrep)
tgrep --json "fn main" .

# Формат file:line:col:text для редакторов
tgrep --vimgrep "unwrap()" .

Быстрый листинг проиндексированных файлов
#

# Мгновенно показывает список всех файлов без сканирования диска
tgrep --files .
tgrep --files -t python .

Поиск в обход индекса (--no-index)
#

Если вам разово требуется классическое сканирование диска в обход сервера и индекса:

tgrep "query" . --no-index

Важные нюансы
#

  1. Репозитории без .git: если вы индексируете обычную папку без инициализированного git-репозитория, добавьте флаг --no-require-git, чтобы tgrep учитывал имеющийся .gitignore:
    tgrep index . --no-require-git
    tgrep serve . --no-require-git
  2. Соблюдайте одинаковые флаги: флаги исключений (--exclude, --max-filesize, --no-ignore) должны быть одинаковыми у tgrep index и tgrep serve.
  3. Лимит размера файлов: по умолчанию tgrep пропускает файлы больше 64 МБ, чтобы тяжелые сгенерированные артефакты и бандлы не раздували индекс. Если нужно снять лимит, используйте --no-max-filesize.
  4. AI-агенты (Cursor, Claude Code, Opencode): tgrep изначально создавался как инструмент для агентов. За счет субсекундных ответов агент не тратит время на ожидание grep по огромным репозиториям.

Итог
#

Для небольших проектов старый добрый ripgrep остается непревзойденным классическим вариантом.

Но если вы работаете с крупными проектами, монорепозиториями на десятки тысяч файлов или автоматизируете работу AI-агентов, связка tgrep index + tgrep serve превращает долгий поиск в мгновенное действие.

Related