КЕЙСЫ
12 июня 2026 г. 7 мин 4

Свой git-хостинг внутри трекера: как мы встроили просмотр кода, диффы и деплой в систему управления проектами

Свой git-хостинг внутри трекера: как мы встроили просмотр кода, диффы и деплой в систему управления проектами

Код проекта живёт в git, а работа над проектом - в трекере: задачи, сроки, переписка с клиентом, тайм-трекинг. И между ними - пропасть. Чтобы посмотреть, что именно поменялось в последнем коммите, разработчик уходит в отдельный git-сервис с чужим интерфейсом, а тимлид, который хочет быстро глянуть диффы по задаче, туда обычно и не доходит. Мы закрыли этот разрыв: встроили полноценный просмотр репозиториев прямо в наш трекер проектов. Коммиты, ветки, файлы, диффы как в настоящем git-хостинге - в одном окне с задачами. В этом кейсе разбираем, как это устроено на нативном git и почему мы заодно отказались от стороннего git-сервера в деплое.

Задача: код и работа над ним - в одном продукте

Мы развиваем собственный трекер - систему управления проектами, задачами и временем. В нём уже живут проекты, канбан, тайм-трекинг, вики, чаты и даже почта. Не хватало кода. Для хранения репозиториев мы использовали стороннее self-hosted git-решение (Gitea), но у него два минуса: отдельный интерфейс, в который надо переключаться, и лишний сервис в инфраструктуре. Мы захотели:

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

  • Свой интерфейс, а не чужой - под нашу дизайн-систему, без визуального разнобоя между разделами.

  • Без обёрток над чужим API: не «встроить Gitea в iframe», а сделать собственное хранилище и собственный просмотр.

  • Минус один сервис в инфраструктуре: меньше движущихся частей - меньше точек отказа.

Решение: всё на нативном git

Ключевое инженерное решение кейса - не писать свою реализацию git и не тащить JavaScript-порт git в зависимости. Движок у нас уже есть: это сам git, установленный на сервере. Бэкенд трекера обращается к нему напрямую - запускает git как процесс и читает результат. Никаких новых тяжёлых зависимостей, полная совместимость с любым репозиторием, предсказуемое поведение.

Что это даёт на практике: трекер читает историю коммитов, содержимое веток, дерево файлов и диффы ровно так, как их видит сам git. Мы написали собственный парсер унифицированного диффа - он превращает «сырой» вывод git в структуру файлы → блоки изменений → строки, которую уже удобно рисовать в интерфейсе с подсветкой и номерами строк.

Раздел Git в трекере: выбор репозитория и ветки, список коммитов, вкладки «Коммиты» и «Файлы»

Диффы - как в настоящем git-хостинге

Главное в работе с кодом - быстро понять, что изменилось. Поэтому диффам мы уделили больше всего внимания и сделали их привычными для тех, кто живёт в GitHub и GitLab:

  • Дерево изменённых файлов с количеством добавленных и удалённых строк по каждому файлу - сразу видно масштаб и где искать.

  • Добавленные строки - зелёным, удалённые - красным, с номерами строк до и после. Привычная и читаемая раскраска, а не блёклый «дефолт».

  • Подсветка синтаксиса прямо в диффе и при просмотре файлов - код читается, а не сливается в серую массу.

  • Клик по файлу в дереве прокручивает прямо к его изменениям - не нужно листать огромный дифф руками.

Дифф коммита: дерево изменённых файлов с +/- по каждому, зелёные и красные строки, подсветка кода

Просмотр файлов в любой ветке

Помимо диффов, можно просто ходить по репозиторию: переключить ветку, раскрыть дерево папок и открыть любой файл - с подсветкой синтаксиса. Удобно, когда нужно быстро свериться с актуальным состоянием кода или показать коллеге конкретный кусок, не клонируя репозиторий к себе.

Просмотр файла в выбранной ветке: дерево каталогов и содержимое с подсветкой синтаксиса

Картинки в диффах - до и после

Отдельно сделали то, чего часто не хватает: изменения картинок видно глазами. Если в коммите поменяли логотип, иконку или фотографию, дифф показывает их рядом - «было» и «стало», - а не просто строчку «бинарный файл изменён». Для команды, где дизайн и фронтенд идут вместе, это экономит кучу переключений между инструментами.

Дифф изображений: версии «было» и «стало» показаны рядом

Подключение репозиториев и состояние в ссылке

Репозитории подключаются в пару кликов: администратор указывает имя и путь к git-каталогу на сервере - ветка по умолчанию определится сама. Так в трекер заехали все рабочие репозитории команды.

Ещё один важный для удобства момент - состояние раздела зашито в адрес страницы: выбранный репозиторий, ветка, вкладка, открытый коммит или файл. Ссылку на конкретный дифф или файл можно скинуть коллеге в задачу, и он откроет ровно то же самое. Раздел открывается уже готовым с сервера (серверный рендеринг), без «моргания» и догрузки после открытия страницы.

Подключение репозитория: имя, путь к git-каталогу, ветка по умолчанию

Бонус: мы вообще ушли со стороннего git в деплое

Раз уж репозитории читаются нативным git на нашем сервере, логично было сделать следующий шаг и убрать сторонний git-сервис из процесса выкладки. Теперь у нас свой git прямо на боевом сервере и деплой по принципу «запушил - выкатилось»:

  • Центральный репозиторий (bare-репозиторий) лежит на нашем сервере - в него и пушим, как раньше в сторонний сервис.

  • Хук на стороне сервера ловит push в нужную ветку и сам обновляет код, ставит зависимости, собирает приложение и перезапускает процессы. Ветка для теста - выкатывается на тестовый контур, основная - на прод.

  • Миграции базы накатываются автоматически при старте. От разработчика - один git push, всё остальное делает сервер.

В результате из цепочки выпал целый внешний сервис: одной движущейся частью в инфраструктуре меньше, а поведение деплоя теперь полностью наше и прозрачное.

Стек и инженерные решения

Раздел кода - модуль внутри монорепозитория трекера, поэтому интерфейс, бэкенд и база едины, а код нативно соседствует с задачами и проектами.

  • Бэкенд: NestJS. Чтение репозиториев - обращение к нативному git как к процессу (без сторонних git-библиотек), плюс собственный парсер унифицированного диффа в структуру для отрисовки.

  • Фронтенд: Nuxt 3 с серверным рендерингом (SSR). Раздел и открытый дифф/файл приходят готовыми с сервера; подсветка синтаксиса - на клиенте.

  • Состояние в URL: репозиторий, ветка, вкладка, коммит и файл зашиты в адрес - ссылки на конкретные изменения шарятся и переживают перезагрузку.

  • Деплой: свой bare-репозиторий на сервере + серверный хук push-to-deploy, без внешнего git-сервиса.

Отдельно повозились с серверным рендерингом за авторизацией и согласованием дат между сервером и браузером - это классические подводные камни SSR, которые мы закрыли, чтобы раздел открывался мгновенно и без ошибок гидратации.

Результат

Код теперь живёт там же, где работа над ним. Тимлид и менеджер видят коммиты и диффы рядом с задачами и не идут за этим в отдельный сервис; разработчик переключается между «что в задаче» и «что в коде» в одном окне.

  • Просмотр репозиториев внутри трекера: коммиты, ветки, файлы, диффы с подсветкой и картинками - в едином интерфейсе.

  • Свой интерфейс под нашу дизайн-систему, без переключения в чужой сервис.

  • Минус сервис в инфраструктуре: хранение кода и деплой - на нативном git, своё и прозрачное.

  • Шарящиеся ссылки на дифф или файл, которые удобно кидать прямо в задачу.

Это наш типичный подход: вместо набора разрозненных сервисов - единая система, где всё связано. Так же мы недавно встроили в трекер полноценную почту с клиентами, а вообще делаем веб-системы и автоматизацию под задачи бизнеса - от CRM и личных кабинетов до внутренних инструментов, которые экономят команде часы рутины.

Частые вопросы

Это обёртка над GitHub или GitLab?

Нет. Это собственное хранилище репозиториев на нашем сервере и собственный просмотр на нативном git, а не интеграция с чужим хостингом. Поэтому интерфейс полностью наш и данные - у нас.

Зачем своё, если есть GitHub/GitLab/Gitea?

Чтобы код был в одном продукте с задачами, сроками и перепиской, под единым интерфейсом, и чтобы убрать лишний сервис из инфраструктуры. Для команды, которая живёт в трекере, это меньше переключений и меньше движущихся частей.

Можно ли так же сделать для нашей команды?

Да. Подход переносимый: нативный git как движок, свой просмотр и свой push-to-deploy. Объём зависит от того, что нужно - только просмотр коммитов и диффов или ещё и собственный хостинг с выкладкой.

Сколько стоит такая разработка?

Зависит от глубины: базовый просмотр репозиториев и диффов - одна история, полноценный git-хостинг со своим деплоем - другая. Оценку даём после короткой аналитики ваших сценариев.


Нужна система, где код, задачи и процессы собраны в один продукт - или встроенный инструмент под ваши процессы? Обсудим задачу и предложим решение: разработка веб-систем и автоматизация.