Back

Использование Git Subrepos для управления большими кодовыми базами

Использование Git Subrepos для управления большими кодовыми базами

Когда ваша frontend-команда использует общие утилитарные библиотеки или UI-компоненты в нескольких репозиториях, возникает фундаментальный вопрос: как синхронизировать этот общий код, не создавая трений в рабочем процессе? Git submodules существуют, но раздражают разработчиков своей сложностью. Git subtree работает, но может сжимать историю способами, которые усложняют внесение изменений в upstream, в зависимости от вашей стратегии слияния.

Именно здесь сторонние инструменты, такие как git-subrepo, предлагают альтернативный подход к управлению общим кодом в Git — подход, который встраивает внешние репозитории непосредственно в вашу кодовую базу, стремясь обеспечить более удобный опыт для разработчиков.

Ключевые выводы

  • Git subrepo — это сторонний инструмент, а не встроенная функция Git, который встраивает внешние репозитории как обычные файлы, упрощая клонирование и онбординг по сравнению с submodules.
  • Он находится между submodules (точная привязка к коммиту, сложный рабочий процесс) и subtree (объединённая история, настраиваемое сохранение), предлагая прагматичную золотую середину.
  • Инструмент хорошо подходит для общих внутренних пакетов, форкнутых зависимостей и постепенной миграции к монорепозиторию в больших кодовых базах.
  • Внедрение git-subrepo вводит компромиссы, связанные с установкой инструмента в CI, сжатой историей при pull и зависимостью от поддержки сообщества.

Что такое Git Subrepo (и чем он не является)

Git subrepo — это не встроенная функция Git. Это поддерживаемый сообществом инструмент, который предоставляет альтернативу Git submodules и рабочим процессам на основе subtree для вендоринга зависимостей с помощью Git. Инструмент клонирует внешний репозиторий в подкаталог вашего проекта, отслеживая метаданные в файле .gitrepo, а не требуя специальной конфигурации Git.

В отличие от submodules, участникам не нужно выполнять дополнительные команды после клонирования — встроенный код существует как обычные файлы в вашем репозитории. В отличие от subtree, который может либо сохранять, либо сжимать историю upstream в зависимости от способа использования, git-subrepo отслеживает связь с upstream отдельно и обычно по умолчанию сжимает изменения upstream при pull.

Git Subrepo vs Submodule vs Subtree

Понимание компромиссов помогает выбрать правильный подход для вашей команды.

АспектGit SubmoduleGit SubtreeGit Subrepo
Модель интеграцииУказатель на внешний коммитСлияние в репозиторийКлонирование как обычные файлы
Обработка историиОтдельная, связаннаяСжатая или сохранённаяОбычно сжатая при pull, отслеживается через метаданные
Поведение при клонированииТребует --recurse-submodulesРаботает нормальноРаботает нормально
Синхронизация с upstreamРучное обновление через checkoutSubtree pull/pushSubrepo pull/push
Воспроизводимость в CIТребует тщательной настройкиОбычно надёжнаТребует установки инструмента

Submodules хорошо работают, когда вам нужна точная привязка к коммиту, и ваша команда понимает рабочий процесс. Команды должны использовать актуальные версии Git и избегать клонирования недоверенных репозиториев с рекурсивной инициализацией submodules, поскольку рекурсивные паттерны исторически создавали проблемы безопасности при небрежном использовании.

Subtree объединяет внешний код напрямую, что упрощает клонирование, но может усложнить внесение изменений в upstream. История может быть полностью сохранена или сжата в зависимости от выбранной вами стратегии.

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

Когда Git Subrepo имеет смысл

Рабочий процесс git-subrepo подходит для конкретных сценариев в больших кодовых базах:

Общие внутренние пакеты: Когда несколько приложений используют общую библиотеку компонентов, git-subrepo позволяет каждой команде вендорить библиотеку, сохраняя возможность отправлять исправления в upstream.

Форкнутые зависимости: Если вы поддерживаете пропатченную версию библиотеки с открытым исходным кодом, git-subrepo отслеживает связь с вашим форком без церемоний submodules.

Постепенная миграция к монорепозиторию: Команды, переходящие к монорепозиторию, могут использовать git-subrepo для постепенной консолидации репозиториев.

Компромиссы, которые следует учитывать

Git subrepo не является универсально лучшим решением — он вносит свою собственную сложность:

Конфликты слияния: Когда и ваш репозиторий, и upstream изменяют одни и те же файлы, разрешение конфликтов требует понимания обеих кодовых баз. Это справедливо для всех подходов встраивания, и git-subrepo не устраняет это.

Сохранение истории: По умолчанию git-subrepo сжимает коммиты upstream при pull. Если вам нужна полная история коммитов, subtree без сжатия может подойти лучше.

Соображения CI: Ваш конвейер сборки должен иметь установленный git-subrepo для выполнения операций синхронизации. Это добавляет зависимость, которой избегают submodules и subtrees, поскольку они используют встроенные команды Git.

Бремя поддержки: Как сторонний инструмент, git-subrepo зависит от поддержки сообщества. Оцените, может ли ваша команда справиться с потенциальными пробелами в поддержке и соответствует ли уровень активности проекта вашим долгосрочным потребностям.

Базовый рабочий процесс Git-Subrepo

После установки git-subrepo основные команды просты:

# Клонировать внешний репозиторий в подкаталог
git subrepo clone https://github.com/your-org/shared-utils packages/utils

# Получить изменения из upstream
git subrepo pull packages/utils

# Отправить локальные изменения обратно в upstream
git subrepo push packages/utils

Файл .gitrepo в каждом каталоге subrepo отслеживает URL upstream, ветку и последний синхронизированный коммит.

Заключение

Git subrepo предоставляет прагматичную золотую середину для управления общим кодом в Git, когда submodules кажутся слишком сложными, а рабочие процессы subtree не подходят для вашей модели внесения изменений. Он особенно хорошо работает для frontend-команд, вендорящих внутренние пакеты в нескольких репозиториях.

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

Часто задаваемые вопросы

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

Git subrepo отслеживает последний синхронизированный коммит в файле метаданных .gitrepo внутри подкаталога. Это обеспечивает форму закрепления версии, хотя она менее явная, чем у submodules, которые записывают точный SHA коммита в дереве родительского репозитория. Вы контролируете, когда получать новые изменения из upstream, поэтому закреплённая версия обновляется только при выполнении git subrepo pull.

Он может работать для вендоринга форкнутых или пропатченных библиотек с открытым исходным кодом, где вам нужно отслеживать изменения upstream и отправлять модификации обратно. Однако для неизменённых сторонних зависимостей менеджеры пакетов, такие как npm или yarn, обычно более подходят, поскольку они предлагают версионирование, lockfiles и экосистемные инструменты, которые git-subrepo не предоставляет.

Встроенный код останется нетронутым в вашем репозитории, поскольку он существует как обычные файлы. Однако вы потеряете возможность получать будущие обновления или отправлять изменения обратно в upstream. Вам нужно будет обновить файл метаданных .gitrepo, чтобы указать на новый remote, если репозиторий переместится, или просто продолжить использовать вендоренный код как статический снимок.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay