Dev48
ЯЗЫК
  • О нас
  • Услуги
  • Индустрии
  • Технологии
  • Статьи
  • Контакты
Забронировать звонок
    Главная/Статьи/Kak my sozdali git hranilische dlya millionov proektov na netlify
Dev48

© 2026 · All rights reserved.

Как мы создали Git-хранилище для миллионов проектов на Netlify

Источник: Netlify

Как мы создали Git-хранилище для миллионов проектов на Netlify

Источник: Netlify

Технический обзор того, как Netlify создала Netlify Source: надежное Git-хранилище на S3, масштабируемое кэширование, согласованность push-запросов и поддержка миллионов проектов.

28 сентября 2026 г.•Обновлено: 28 сентября 2026 г.

За последние десять лет Netlify выросла из сервиса непрерывного развертывания и хостинга в более широкую платформу рантайма: функции, краевые (edge) функции, блобы, базы данных, аутентификация, ИИ и многое другое. Но сама разработка по-прежнему оставалась в другом месте — в собственном Git-репозитории пользователя. Код отправлялся туда, мы получали уведомление, а затем собирали, развертывали и обслуживали получившийся сайт. Это была честная работа.

За последние 12–18 месяцев кое-что изменилось.

Все чаще наши пользователи стали отправлять нам файлы напрямую: папку или zip-архив через Netlify Drop, API Netlify, Netlify MCP… или это делает ваш агент. Они также начали собирать и обновлять проекты напрямую с помощью Agent Runners.

Они стали делать это очень часто. В прошлом месяце 93% новых проектов были созданы одним из таких способов; два года назад этот показатель составлял 70%. В абсолютном выражении это несколько миллионов новых проектов в месяц — рост в 14 раз.

Теперь каждому проекту нужен репозиторий Git

Оказывается, хостинги Git выполняли много сложной и полезной работы. Мы не хотим становиться провайдером Git-хостинга, но мы хотим, чтобы каждый проект на Netlify получал преимущества Git.

Когда вы и агент одновременно вносите изменения, вам нужно где-то сохранять незавершенную работу (следовательно… коммит в ветке?), иметь общее понимание того, с чего все началось и что изменилось (следовательно… родительский коммит и дифф?), способ перехватить управление у агента (следовательно… git pull?), способ вернуть свои изменения агенту (следовательно… git push?) и способ включить изменения из вышестоящей ветки перед публикацией ваших собственных (следовательно… git merge или rebase?). Обо всем этом нужно позаботиться при работе с десятками миллионов репозиториев, обеспечив высокую производительность, безупречную целостность данных и масштабируемую экономику единицы ресурса.

… Да, это Git.

Мы случайно, шаг за шагом, пересоздавали Git по кусочкам. Наша вина.

Поэтому мы создали интегрированный, управляемый Netlify Git-репозиторий для каждого проекта, который попадает на Netlify без подключенного хостинга (то же самое мы представили в прошлом месяце в беседе с Даной Лоусон о будущем Git, где мы использовали наше внутреннее название Netlify Source). Эти репозитории поддерживают тот же протокол Git, что и любой другой удаленный репозиторий. Наша инфраструктура сборки, Agent Runners, ваш редактор и ваш собственный агент — все они могут работать с ними. Продолжить работу с того места, где остановился агент, должно быть так же привычно, как клонировать репозиторий.

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

Архитектура

S3 как надежный источник истины

Сначала минутный ликбез по внутреннему устройству Git. Git хранит содержимое файлов (блобы), списки директорий (деревья) и коммиты как объекты, идентифицируемые хэшами. Коммит указывает на дерево своего снимка состояния и на родительские коммиты. Эти объекты неизменяемы; ветка, такая как main, — это маленький указатель, который меняется. Указатели веток — это тип ссылок (refs). Git может хранить объекты по отдельности («слабые объекты», loose objects) или упаковывать их в packfiles.

Наш Git-сервис написан на Go и запускает бинарный файл Git для локального bare репозитория (полная история, без извлеченного рабочего каталога). Сам Git поддерживает Smart HTTP, согласовывает передачу объектов с клиентом и обрабатывает пакетные файлы (packfiles).

Задача нашего сервиса — перемещать данные между S3 и локальным репозиторием до и после запуска Git. S3 хранит надежные данные: слабые объекты и пакетные файлы в родных форматах Git, а также ссылки в виде небольших записей JSON. Каждый под хранит локальный кэш репозиториев на диске, удаляя наименее используемые из них, когда требуется пространство.

Для клонирования или выборки (fetch) сервис сначала синхронизирует локальные ссылки и объекты из S3, а затем позволяет Git обслуживать их с диска. При холодном кэше это означает инициализацию «голого» (bare) репозитория и загрузку его данных. При горячем кэше мы все равно проверяем S3 и скачиваем все недостающие элементы. Если под исчезает, другой восстановит репозиторий из S3 при следующем запросе к этому репозиторию.

Обеспечение надежности git push

git receive-pack — это команда RPC в Git, которая принимает push. Как только она обновила локальный репозиторий, она готова сообщить об успехе. Но под может исчезнуть до того, как эти изменения попадут в S3.

У нас есть два требования: ссылка (например, указатель ветки) никогда не должна опережать объекты, на которые она указывает, и мы никогда не должны сообщать клиенту об успехе до тех пор, пока изменения не будут сохранены в надежном хранилище (S3).

Поэтому мы выполняем следующую последовательность, удерживая локальную блокировку записи (мьютекс Go) для этого репозитория:

  • Синхронизируйте ссылки и объекты из S3, затем передайте полезные данные запроса в git receive-pack.
  • Загрузите новые пакетные файлы и слабые объекты в S3.
  • Обновите ссылки в S3 с помощью условной записи, только если их текущие значения совпадают с нашими ожиданиями.
  • Передайте ответ receive-pack из шага 1 клиенту.

Загрузки объектов могут перекрываться: объекты неизменяемы и идентифицируются своим содержимым. Ссылки изменяемы; два автора могут иметь разные мнения о том, куда должен указывать main.

Мьютекс координирует запросы только в рамках одного пода. Во время деплоя или изменения маршрутизации два пода могут начать работу с тем, что main указывает на коммит A, и попытаться перевести его в B и C. Оба могут загрузить свои объекты, но только один может сдвинуть main из A.

Мы читаем ссылку из S3 и проверяем, что она все еще указывает на A. Это чтение также возвращает ETag — токен для проверки того, изменилась ли сохраненная запись ссылки. Это отличается от хэша коммита Git. Мы записываем новую ссылку с условием If-Match для этого ETag. S3 проверяет условие и выполняет запись атомарно, поэтому изменение между нашим чтением и записью приводит к сбою обновления. Для новой ссылки используется If-None-Match: *, чтобы требовать ее отсутствия.

Если условная запись отклонена, команда push сообщает об ошибке синхронизации хранилища. При ошибке сохранения мы сбрасываем локальный кэш, чтобы следующий запрос восстановил его из S3.

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

Удержание этого ответа может оставить соединение неактивным в течение нескольких минут при большой операции push. Клиенты и прокси обычно имеют свое мнение на этот счет. Когда клиенты это поддерживают (большинство должно в наши дни), мы отправляем (и сбрасываем буфер!) сообщения о прогрессе Git side-band каждые десять секунд во время синхронизации с S3.

Прирост производительности

Одним из быстрых улучшений стал отказ от собственной реализации команды «rebase» для Agent Runners. Раньше мы просили агента повторно применить накопленный за время выполнения дифф поверх исходного кода более свежего деплоя. С интегрированным Git-репозиторием обновление обрабатывает git merge. Агент все еще может помочь с разрешением конфликтов, если таковые имеются. Чистые слияния позволяют полностью пропустить сеанс агента, в результате чего большинство таких операций занимают около одной секунды (и ноль токенов!) вместо нескольких минут. Публикация результатов работы агента теперь (в большинстве случаев) представляет собой просто git merge в main с последующим push.

Подготовка рабочей среды исходного кода для сборок и запусков агентов занимала в среднем 0,76 с (медиана) и 2,26 с на уровне p95 в период с 7 по 13 сентября 2026 года. Для проектов, подключенных к GitHub, этот же этап занимал 0,84 с и 2,51 с. Для относительно простого Git-сервиса, постоянным хранилищем для которого служит S3, это достаточно близко к GitHub, чтобы казаться ничем примечательным — в этом и заключалась суть.

Хостинг Git в 2026 году

Мы создавали это не для того, чтобы с кем-то конкурировать. Наша цель заключалась в том, чтобы у каждого проекта, попадающего на Netlify без Git-хостинга, появился настоящий хостинг — незаметно для пользователя. Но поскольку сейчас несколько команд решают схожие задачи, стоит сравнить ограничения.

Cursor Origin создает полноценную среду разработки. Ее бэкенд Continuity также рассматривает объектное хранилище как постоянное, а локальные репозитории — как кэши, но он оптимизирован под другую задачу: высокую пропускную способность записи и конкуренцию в рамках одного репозитория. Он публикует пуши через журнал упреждающей записи и пакетно обновляет свой индекс; мы выгружаем объекты Git и обновляем каждую ссылку напрямую.

East River Source Control переосмысляет хранение для растущих репозиториев и более интенсивной параллельной разработки. Они строят свое решение поверх Jujutsu, стремясь устранить узкие места производительности для огромных монорепозиториев и заглядывая за пределы Git.

Code Storage от The Pierre Computer Company предлагает программируемое хранилище Git с API, разработанными для машин, на базе кворума реплик.

Entire объединяет распределенный хостинг Git с сеансами агентов и обсуждениями, стоящими за кодом.

Для сравнения: опубликованная архитектура Spokes от GitHub реплицирует пуши на файловых серверах и требует наличия кворума. Gitaly от GitLab хранит авторитетные репозитории в файловых системах обслуживающих узлов, в то время как Praefect координирует несколько реплик. Эти системы должны отслеживать и защищать копии репозиториев на этих узлах. Мы решили положиться на гарантии доступности, долговечности и атомарности S3, а также на его условную запись. Это также позволяет нам сохранять относительную простоту архитектуры.

GitLab тоже исследует это разделение. Предложение Scaling Git сделало бы объектное хранилище авторитетным, а узлы Gitaly — кэшами. В нем предлагаются пользовательские бэкенды хранения Git и единый указатель манифеста для атомарной публикации согласованного снимка репозитория. Мы сохранили собственные форматы объектов Git и используем условную запись на уровне ссылок с описанной выше более узкой атомарностью.

Что дальше

Реорганизация того, как мы храним исходный код и управляем им «под капотом», была лишь первым незаметным шагом. Благодаря этому фундаменту открылся целый ряд потенциальных возможностей.

Чего дальше не будет

Netlify всегда выступал за свободу выбора и компоновки. Ничего не меняется и не изменится в отношении Git-хостингов, которые можно подключать к Netlify — GitHub, GitLab, Bitbucket, Azure DevOps и, с прошлой недели, Cursor Origin. Если рабочий процесс вашей команды уже связан с одним из них, вам по-прежнему следует использовать Netlify именно так.

Речь идет о том, чтобы предоставить проектам, попадающим на Netlify без одного из этих хостингов, ту же основу, а не о том, чтобы переманивать кого-то с уже выбранной платформы. И поскольку это настоящий репозиторий Git, использующий стандартный протокол, с нашей стороны тоже нет никакой привязки к системе. Клонируйте его, добавляйте любой нужный удаленный репозиторий и делайте push. Вы даже можете экспортировать свой код на GitHub в один клик.

Все, что появится в будущем, не будет эксклюзивом для проектов с интегрированным репозиторием Git. Мы можем это гарантировать.

Больше подробностей во второй части

Нам еще многое предстоит рассказать о технической архитектуре, проблемах масштабирования, безопасности и о том, как мы перенесли миллионы существующих проектов в эту систему. Следите за выходом второй части этой серии.

← Все статьи

Ещё в разделе «Разработка ПО»

Все →
Air Teams: внедрите лучшие агентные рабочие процессы во всей команде и автоматизируйте повторяющиеся задачи
JetBrains

Air Teams: внедрите лучшие агентные рабочие процессы во всей команде и автоматизируйте повторяющиеся задачи

Выпущен Rider 2026.2.3!
JetBrains

Выпущен Rider 2026.2.3!

Более надежная схема компиляции для модулей Kotlin Multiplatform
JetBrains

Более надежная схема компиляции для модулей Kotlin Multiplatform

BOB в гостиничном бизнесе: руководство по Business on Books и OTB
Hotelogix

BOB в гостиничном бизнесе: руководство по Business on Books и OTB

Insyde® Software подтверждает лидерство в области безопасности микропрограмм на конференции FTA 2026
Insyde Software

Insyde® Software подтверждает лидерство в области безопасности микропрограмм на конференции FTA 2026

Обзор Sennheiser Momentum 5: великолепный звук, невероятное время автономной работы и минимум компромиссовПресса
Momentum

Обзор Sennheiser Momentum 5: великолепный звук, невероятное время автономной работы и минимум компромиссов

Ещё от Netlify

Репозитории Cursor Origin собираются, тестируются и развертываются на Netlify
Netlify

Репозитории Cursor Origin собираются, тестируются и развертываются на Netlify

Мероприятие Build with Netlify прошло в Атланте
Netlify

Мероприятие Build with Netlify прошло в Атланте

Участвуйте в челендже WebMCP от OpenAI вместе с Netlify
Netlify

Участвуйте в челендже WebMCP от OpenAI вместе с Netlify

Новые уточняющие вопросы в Agent Runners
Netlify

Новые уточняющие вопросы в Agent Runners