Pull to refresh

Comments 85

очень интересно наблюдать как хайпили по микросервисам против монолита, а сейчас за монорепо против сервис-реп
Мне нравится делать
docker-compose up
в корне монорепы и получать целиком рабочий проект. И эту команду выполняет каждый разработчик каждый день и она редко ломается, показывает как проект работает целиком. Монорепа уменьшает страхи сделать ещё один подпроект в виде микросервиса (в большой компании вам нужно пройти все круги ада на одобрение такого и рассказать всей команде, что нужно запускать +1 проект в деве). Единый процесс CI/CD, который крайне просто менять, потому что он один, а не 10+ в разных проектах (infrastructure as code, сейчас код деплоя лежит рядом с кодом приложения).

На другой стороне примеры проектов с десятком репозиториев, которые поддерживаются уже второй-третий год. Чтобы запустить каждый нужно немного магии, немного магии * 10 — это крайне МНОГО магии. Часто граф зависимостей не описан.

В идеальной компании полирепозиторий — хорошо, но такий крайне мало. В стартапе на 3-5 человек 10 репозиториев не нужны.

PS. Мы держим каждый frontend на react отдельно, потому что чисто фронтендщики не хотят заморачиваться или это не позволяет делать windows без боли. А весь бек лежит в монорепе.
Смотрите, как это сделано у нас: есть репозиторий с инфраструктурой, к нему через git-submodules подключены уже конкретные проекты. По умолчанию субмодули не выкачиваются. А сборщик умеет выкачивать субмодули по требованию. При этом разработчик может в любой момент переключить любой субмодуль на любую ветку. А когда надо сделать релиз — в инфраструктурной репе комитятся новые ревизии субмодулей.
Я боюсь submodules. Только печальные практики с ним. Скорее всего я не умею готовить. Может подскажите полезные статьи?
Крайне сложно работать в ветках и не сломать себе мозг при обновлении нескольких submodules. Я сломал.
Переходили с subtree на submodule пару лет назад. Сперва было больно, а потом ничего, понравилось. Из плюсов — быстрая синхронизация кода (и предсказуемая)
из минусов — надо всегда держать в голове, какие коммиты ты должен сохранить и не ребейзить (обычно это все release/* ветки, но бывают исключения).
Мне они нравятся из-за какой-то своей ODR-ности, что ли.
В один репозиторий 10-15 сабмодулей подключается если что.
UFO just landed and posted this here
Если вы активно работаете с самими подмодулями, тогда возможно. Из моей практики единственное место которое влекло за собой «поломку» проекта, это вынос части проекта в отдельный подмодуль. В таком случае проблемы были только с выкачиванием\мерджем более старых веток у других людей, и то это разовая проблема.

Сабмодули можно использовать как раз для создания надрепозитрия (или мета-репозитория) вокруг нескольких независимых полиреп. В него можно положить compose для запуска всего проекта целиком как alexesDev любит

Проблема с сабмодули, что они ссылаются на конкретный коммит. Таким образом, держать такой репозиторий в актуальном состоянии довольно трудно. Можно, конечно, автоматизировать, чтобы всегда вытягивать, например, свежие релизные версии… Но не очень понятно, какую проблему это решает. Если хочется запускать полностью всю систему локально, то проще залить артифакты в registry/bintray/куда-то ещё и точно также запустить docker-compose

git-subtree (https://habr.com/post/429014/) по идее должен решать эту проблему, но я его пока не использовал, так что ничего сказать не могу.


Публиковать артефакты — это тормоза, мусорные коммиты с подъёмом версий зависимостей, конфликты в версиях при мёрже веток и разъезжание кода в репе с тем, что опубликовано. В общем, боль и страдания.

subtree сильно хуже, когда есть несколько слабо зависимых команд и надо периодически между ними синхронизировать код.
сабмодули позволяют грубо говоря всегда иметь точно ту же самую версию кода.
subtree в принципе может быть вариантом, если конкретный репозиторий всегда меняет ровно одна команда и никакая другая (так что конфликты исключены). Иначе — не в ту сторону решенный конфликт является багом замедленного действия (который ты не выявишь diff-ом, ибо дифф-то и должен быть в ситуации правок с нескольких источников).

Есть еще проблема с бранчами, когда в рамках одной фичи нужно отбранчить код в нескольких, связанных сабмодулями репозиториях. Дело в том, что ссылки на сабмодули в фича-бранче родительского репозитория будут указывать на коммиты в мастере. Тогда даже автоматизация через git submodule update не помогает. Есть волшебная пилюля для такого сценария?
А как вы собираетесь деплоить эти связанные изменения?
Я бы сказал, что если у вас есть сильная связь между репозитоиями, вы неправильно определили границы.
Если все же границы определены верно, то не нужно писать этот код вместе — добавьте изменения в первый репозиторий, задеплойте его, потом добавьте во второй — задеплойте его.

В гите нет веток. Есть только ревизии и указатели на ревизии. Субмодуль может указывать на любую ревизию. Даже если после неё нет ревизии, на которую указывает мастер. А git submodule update не смотря на название просто выкачивает эту самую ревизию в рабочую копию. У гита всё плохо с командами, да.

А чем это отличается от обычного монорепа? Например, тот же svn уже стопицот лет умеет partial checkout, и каждый подкаталог, и даже файл можно выкачать нужной ревизии. Только, в отличие от git'а, выкачивается не вся история, а только нужная ревизия.

Это правда, что в проекте из 2-3 человек не нужно несколько репозиториев. Это просто добавить слишком много накладных расходов. Так что это вполне естественно начинать проект с монорепозитория. Проблемы начинаются тогда, когда у вас 200+ разработчиков, 500+ комитетов в день и билд занимает 40 минут.
Главное не пропустить тот момент, когда код будет настолько связан, что разделить его уже не получится

Это правда, что в проекте из 2-3 человек не нужно несколько репозиториев. Это просто добавить слишком много накладных расходов.

Это зависит не от количества людей, а от сложности проекта.

Одно из преимуществ, которое мне нравится — подмодули заставляют тебя так декомпозировать код, что ты не можешь сделать проекты A и B взаимозависимыми (если всё правильно организовано). А если случайно так получилось, — это требуется исправить, а результат гарантированно можно проверить, просто собрав эти два подмодуля по-отдельности.

Ещё одно преимещуство — это пакетирование. CI/CD автоматически собирает каждый проект, отдельно его тестирует и пакетирует, например, в свой deb- или rpm-пакет под заданные платформы. Но тут сложнее, т. к. требуется автоматизировать зависимую сборку проектов. Зато не требуются такие надстройки как над монорепозиторием.

Ещё одно преимущество — можно делать глобальный рефакторинг не по всему проекту сразу, а частями через подмодули, таким образом распределив задачу по разным людям. При этом нигде ничего не ломается.
> Это зависит не от количества людей, а от сложности проекта.

И от количества людей тоже (мало людей не смогут нагенерировать поток коммитов и создать проблемный размер для репозитория), так что если 2-3 человека, то основные проблемы монорепозитория не очень проявляют себя.

> Одно из преимуществ, которое мне нравится — подмодули заставляют тебя так декомпозировать код,

Это указано в статье, тоже считаю это преимуществом

> Ещё одно преимещуство — это пакетирование.

вот тут не вижу взаимосвязи с моно- или полирепозиторием, мы в своем монорепозитории собираем отдельные пакеты для каждого микросервиса под разные платформы, работало и на maven, работает и на bazel

> Ещё одно преимущество — можно делать глобальный рефакторинг не по всему проекту сразу, а частями через подмодули

ну прямо скажем, в монорепозитории тоже так можно. Даже более того, (об этом сказано в статье) другого варианта у вас нет даже в монорепозитории из-за неатомарности деплоя.
вот тут не вижу взаимосвязи с моно- или полирепозиторием, мы в своем монорепозитории собираем отдельные пакеты для каждого микросервиса под разные платформы, работало и на maven, работает и на bazel

К сожалению Java хоть и знаю, но в продакшене пока ещё не использую (равно как и монорепозитории, которые с самого начала решил не делать), поэтому мне сложно в этом контексте что-либо оценивать.

Идея, которую я пытался донести в том, что каждый подпроект описывается отдельно и подключается там, где это требуется как подмодуль. При этом сам подпроект обрабатывается Gitlab (CI/CD) как самостоятельный проект, который не знает о существовании чего-либо ещё. При этом для каждого проекта создаётся шаблонный yaml-файл для CI/CD в котором по сути меняется лишь название проекта. А сама сборка осуществляется с помощью ещё одного универсального подмодуля, который подключается к каждому проекту. А уже этот подмодуль берёт из проекта файл конфигурации под каждую платформу для текущего проекта.

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

Если у вас проект целиком запускается на одной машине, это маленький проект ;)
В моей практике была система, минимальная конфигурация которой содержала 20 виртуалок. Никто даже не пытался запускать ее на локальной машине, т.к. там было несколько инстансов Оракла с кросс-локейшн репликацией

А с меньшим количеством инстансов оракла эта система не способна работать?

Не поверите, но нет :)
Это не ноды одного кластера, а независимые подсистемы
В подробности вдаваться не буду, просто поверьте на слово ;)
А разве суть микросервисов не в том, чтобы их можно было запускать и разрабатывать отдельно?

Частично да, но иногда, к сожалению, нужно протестировать интеграционные сценарии. А что того хуже, иногда их нужно ещё и продебажить. Так что хорошо иметь возможность запустить хотя бы часть системы (несколько сервисов, в зависимости от воспроизводимого сценария) локально из IDE в дебаг режиме

Я в основном отвечал на «docker-compose up и все запущено». Как-то это не микросервисно. Поднимать несколько сервисов можно и иногда нужно, но это не должно быть обязательным требованием.
Автор неправ. Аргументы за — какие-то высосанные из пальца. Из серии «сам придумал — сам с собой поспорил».
Потому что, на большом масштабе монорепозиторий будет решать все те же самые проблемы, которые решает и полирепозиторий, но при этом провоцируя вас к сильной связанности вашего кода и требуя невероятных усилий по увеличению масштабируемости вашей системы контроля версий. Таким образом, в среднесрочной и долгосрочной перспективе монорепозиторий не дает никаких организационных преимуществ, в то время как оставляет лучших инженеров компании с пост-травматическим синдромом (проявляется в виде пускания слюней и бессвязного бормотания о производительности git).

что я подразумеваю под «на большом масштабе»? Нет однозначного ответа на этот вопрос, но т.к. я уверен, что вы спросите меня об этом, давайте скажем, что это около 100 разработчиков, пишущих код фул-тайм.

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

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


На больших проектах монорепозиторий действительно не нужен. Но на малых проектах, или в малых командах (и особенно если всего 1 разработчик), или вообще в начале проекта — монорепозиторий очень удобен. Если проект-прототип получит развитие, то уже далее, в какой-то момент монорепозиторий надо будет разделить.

Проведу некую аналогию — было множество споров, что лучше — монолит или микросервисы. У каждой из архитектур свои + и -. Я считаю что существует промежуточный вариант — микросервисный монолит, который будет жить в монорепозитории. Он хорош на старте проекта, и если проект «взлетит» и получит развитие, то будет рефакторинг в честные микросервисы и разные репозитории.

Ну в статье и говорится не об одном разработчике, а о проекте с 100+ разработчиками.
Могу сказать по своему опыту, про темы совсем невыдуманные. Особенно в части того, что некоторые компании бездумно копируют практики.
В данный момент у нас 200+ инженеров работают над монорепозиторием. Более 100 коммитов в день, билд на CI занимает около 40 минут. Клонирование репозитория с Гитхаба (учитывая поганый Австралийский интернет) занимает больше 10 минут.
Я уж не говорю про индекс в Идее

Так основной посыл статьи — не используйте монорепо вообще никогда. Это тоже бездумная рекомендация. Мой комментарий про ограничения применимости.
Cлушайте, если у вас один разработчик, то у вас не «монорепозиторий», а «репозиторчик». В том смысле, что там мало кода, и вообще пофиг на это. Посыл автора про большие команды. И, в основном, сторонники монорепы эти аргументы и приводят.
У нас тоже монорепа и two-pizza team. Сначала было разделение на 2 репы — бек на джанго и фронт на реакте. Но это было банально неудобно. В итоге слили в один и довольны.

Про тесты — у нас в несколько потоков:
— бек интеграционные
— бек юнит
— фронт тесты
— фронт тест билда

Добавили маленькую проверку изменений в папке backend и frontend в CI чтобы зря не гонять тесты.

Все довольны :)
Надо подчеркнуть, что в статье под «монорепозиторием» понимается не просто «несколько кусков проекта в одной репе» (скажем фронт и бек одного проекта), и даже не «несколько микросервисов в одной репе», а скорее подход trunk-based-development (аля гугл), где:
— одна репа на несколько *продуктов*, с разными командами, циклами релизов и т.п;
— в этой же репе лежат все «общие» компоненты, внутренние фреймворки, сервисы;
— но отсутсвие версий у библиотек/компонентов; по сути версия одна — номер коммита;
— нет (ну или почти нет) внешних зависимостей — вместо этого зависимости включаются в саму репу (подход аля Go).

Поэтому, имхо, немного неуместно говорить «а вот в нашем проекте на 3 человека и 5 микросервисом монорепа и все зашибись». Речь все же идет про разные «монорепы».
тогда это хорошо бы в дисклеймер к статье
Как по мне, отвечая на вопрос полирепозиторий или монорепозиторий — нужно ориентироваться на условия в которых будет выполняется разработка, а также личные предпочтения участников разработки. Остальное же, по моим мироощущениям, не так и важно. Если команде проекта удобно, то какая разница какой подход к организации репозитория они используют?!
По сути автор говорит именно об этом, но суть в том, что подход с монорепозиторием на определенном масштабе начинает добавлять проблем с производительностью VCS и не только, которые нужно как-то решать. Гугл может себе позволить иметь сотни разработчиков, работающих годами над этими проблемами. Может ли ваша компания?
Примечательно, что старый добрый SVN этих проблем не имеет. Выкачал любую часть репозитория и работай с ней как с отдельным репозиторием. Разве что рано или поздно появляются всякие бранчи в транках и транки в бранчах.
Ну говорят, что Яндекс его и использует для своего монорепо в Поиске
UFO just landed and posted this here
Можете подробнее рассказать про свой опыт?

Оторвано от контеста.
В случае с тем же JS'ом — есть lerna, хочешь монорепку — делай моно, хочешь полирепку — делай поли через git submodules. Погоды особо не делает.


В разных языках — разные пакетные менеджеры, и очень мало жизнеспособного инструментария для монорепок.

>> В разных языках — разные пакетные менеджеры, и очень мало жизнеспособного инструментария для монорепок.

Не вижу проблемы положить несколько независимых продуктов в один реп в разные каталоги.
В php-проектах использую composer. Очень удобно обозначить зависимости и сохранить lock-файл, на проде просто установка из lock-файла. На случай если очень важно не потерять пакеты, можно сделать свой собственный «proxy» в виде satis. Не представляю что должно произойти чтобы пришлось отказаться от composer и хранить либы в репозитории.
Еще есть вопрос по поводу универсальных либ которые удобно один раз написать и потом только использовать. Проблема в том что отладив либу для проекта, для другого почти наверняка придется сделать изменения которые могут сломать первый. Писать либу так чтобы было супер универсально далеко не всегда получается. Возможно в этом случае и полезны монорепозитории.

Забавно, а мы сейчас в команде раздумываем над объединением наших пакетов в одно монорепо. Аргументы у нас такие:


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

Размер команды – 10 человек. Если было бы на порядок больше, то там уже пришлось бы как-то разделять зоны отвественности и разъезжаться по отдельным репозиториям.

Половину аргументов можно сходу отметать по той простой причине, что гит — это не про монорепы.
Что вы имеете в виду? Все исходники Windows хранятся в Гит, также как и ядро Linux.
Ну так-то исходники винды лежат не совсем в гите, а линукс — это очень маленький проект по сравнению с кодовой базой фейсбука
Тут возникает резонный вопрос: а нужно ли создавать себе проблемы с большими репозиториями, чтобы потом их героически решать? Не проще будет распилить большой проект на отдельные части?
Очевидно, до тех пор, пока вы не выросли до размеров гугла, фейсбука или даже яндекса — не нужно :)

Когда в команде несколько десятков разработчиков, начинается гонка за коммит в head. В линуксе это работает благодаря организационной структуре: там изменения льются в апстрим по дереву доверия, и в каждом узле небольшое код-во разработчиков.

Для решения такой проблемы монорепощиторщики придумали свой тулинг :) называется мерджбот
Например prow от Goggle bentheelder.io/posts/prow или сервис mergify.io

Я работал с большими кодовыми базами с использованием обоих подходов.


Монорепы — это на порядок более удобный и продуктивный подход (полирепы вспоминаю как страшный сон), если у компании есть ресурсы для настройки (а возможно, и написания с нуля) инструментов для работы с ними. Facebook и Google выкладывают много полезного для этого кода в открытый доступ (Kythe, Bazel, Hg-experimental), но инвестировать в инфраструктуру придётся много.


Не выйдет просто взять и начать сваливать весь код в одну кучу.

Проблема со всеми этими проектами описана в статье.
Все они обладают очень сильной привязкой к специфике кодовой базы разработчика. Их просто невероятно сложно начать использовать. Говорю это, как человек, переведший монорепозиторий с мавена на bazel

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

Именно это и говорится в статье — есть ровно 20+- компаний в мире, которые умеют в монорепо. Это гугл, фейсбук, твиттер, яндекс, может быть, кто-то еще.
Остальным не надо даже пытаться, т.к. правильных инструментов у вас нет, как и ресурсов на их создание.
А в какой компании вы нынче монорепу используете?
И какие основные языки/технологии в вашей деятельности?
А вы в профиль загляните.
С компанией лоханулся, признаю.
Списка языков и технологий там нет.
Есть определенная разница, использовать монорепу для бекэнда на плюсах, фронтенда на TypeScript или мобильных приложения для iOS и Android.
Если работает первый случай — это круто, но не интересно. Если второй и третий — это уже интересней.
Это же гугл. Там в общем и целом один монореп для всего и сразу. C++, Java, Python, Go (который родился в монорепе и поэтому там такой странный для внешнего пользователя менеджмент зависимостей), джаваскрипт, конечно. Под веб, айос, андроид, десктоп и все остальное что может прийти в голову.

Тайпскрипт тоже, да.
Ну и как вам для фронтэнда монорепа? Все ли чудесно и прекрасно?
Нет, не все прекрасно. Но в целом работает.

Пока пользуешься рекомендованным тулингом и зависишь от других внутренних проектов — все в общем даже наверное хорошо.

Интересное начинается когда добираешься до 3p кода (например популярные фреймверки, d3 и прочие antlr'ы).
Интересное начинается когда добираешься до 3p кода

Ну вообще говоря, c 3p не так уж всё и плохо. Как всегда с монорепами, это — проблема тулинга. Написаны инструменты для импорта сторонних зависимостей из разных источников и синхронизации с открытыми репозиториями. Очень многие популярные вещи уже в third_party.


Зато получаем


  • codesearch по всем зависимостям
  • очередной leftpad вам ничего не сломает
  • вместо двух тысяч копий leftpad у вас будет ровно одна
  • версии всех зависимостей всегда консистентные (особенно актуально в каком-нибудь Haskell)
И плюс еще если надо слить/разъединить команды, то на структуре кода это не отражается.
Так-то оно так, да не совсем. Вполне понятно для чего и почему сделано так и как оно сделано, но есть много нюансов.

То же правило одной (на самом деле двух, для переходных периодов) версии — это палка о двух концах. С одной стороны — да, одна версия, которая всеми и используется. С другой стороны — выходит у пакета новая версия с breaking changes и все, у тебя 100+ проектов зависят от старой версии пакета, в репозитории жесткое правило одной версии, это пат. Надо обновить версию пакета и все зависимые проекты. А этим редко кто-то занимается. В результате в third_party свалка из неактуальных версий зачастую неактуальных пакетов, с которыми ничего толком не сделать. Для многих из них еще специально бекпортят фиксы безопасности, потому что нормально обновить не получается и как результат — что-то непонятное на выходе.

Про то, что логика работы менеджмента зависимостей для фронтенда в принципе плохо ложится на рельсы монорепа (не только из-за вопросов версионирования) я расписывать не буду. По большому счету мне в codesearch не нужен код ВНЕШНИХ зависимостей, мне нужно только описание их API (exports.js + typings), которое там так и так присутсвует.

Монореп может все-таки отдать управление ВНЕШНИМИ зависимостями на откуп стандартным инструментам, это ведь даже не сабмодули, просто код, который вам не принадлежит совсем. Гугл не может, по понятным и объективным причинам (security/privacy/legal), компания поменьше — может вполне.
Однако адаптация хороших внешних инструментов под этот чудесный монолит — та еще задача, зачастую просто решаемая в лоб написанием своих собстенных «аналогичных» инструментов.

Я не так давно переводил один фронтенд-проект на 40+ тысяч строк с git/npm/gulp/webpack на эту чудесную монорепу, проклял все. Это еще повезло что он был наполовину на совсместимом наречии написан.
40+ тысяч строк с git/npm/gulp/webpack на эту чудесную монорепу

На какую чудесную монорепу? В чём заключался перевод? Просто переписали билд на bazel/pants/buck?


Перевод проекта с системы сборки X на систему сборки Y, ∀ X, Y — это всегда много скучной, изматывающей, неблагодарной работы.


Я переводил ~500.000 строк кода и двумя десятками приложений на Java с кастомной ANT-сборки на Gradle, утомился. При чём тут монорепы?

На ТУ САМУЮ чудесну монорепу про которую вы пишете выше.

Билд, это не самое интересное, это, как верно замечено, просто много скучной и изматывающей работы.

Самое интересное — это 3p зависимости, которые раньше подтягивались через стандартный для внешнего мира пакетный менеджер, а теперь должны быть частью собственно монорепы. В которой очевидное правило одной версии (очень далеко не всегда последней), определенные сложности с оформлением и добавлением пакетов из внешнего мира, очень плохая концептуальная совместимость с миром современного фронтенда в целом и еще разные сугубо внутренние нюансы.

Ну хотя это ведь тоже часть билда, если разбираться.
реализовывать кросс-модульные фичи — это просто сказка
Знаем-знаем. А потом без пол-литры не разберешь, а где же у этих систем границы. Где собственно зоны отвественности и все такое… Зла нет :)
А потом без пол-литры не разберешь, а где же у этих систем границы. Где собственно зоны отвественности и все такое…

Это самый бредовый аргумент из всей статьи. У нас у каждой большой системы есть свой каталог с OWNERS файлами, в которых написано, кто владеет кодом. В нормальном воркфлоу без аппрува этой команды ничего изменить в их коде не получится. Всегда понятно, где границы, и кто за что отвечает. Сервисы взаимодействуют друг с другом через посылку сообщений поверх gRPC. Сложно представить себе более ясные границы.


Полирепы вас от плохого кода точно не спасут.

Ну OWNERS конечно хорошо, но от проблемы не спасает. Там может много кого, и аппрувят люди, которые далеко не всегда имеют досататочный контекст :)
И взаимодействие через gRPC тоже не панацея. Оно может быть как в пределах одной системы (разбитой на куски), так и разных. Я же не про разбивку на бинари говорю.

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

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


В полирепе так же просто сделать неявную зависимость между модулями: предположения о формате данных, структуре хранилища и т.п. Я точно также могу утверждать, что полирепы поощрают вас, к примеру, хранить фронт-енд и бэк-енд в разных репозиториях, и протокол между ними не генерить из общего IDL по соседству, а писать руками дважды (счастливой отладки при апдейте схемы).
И вот такое я как раз видел сплошь и рядом.

Речь идет лишь о «стимулирует» или «подталкивает», а не о жестких следствиях.

Я точно также могу утверждать, что полирепы поощрают вас, к примеру, хранить фронт-енд и бэк-енд в разных репозиториях, и протокол между ними не генерить из общего IDL по соседству, а писать руками дважды (счастливой отладки при апдейте схемы).
Вот не совсем. Скорее, если культура разработки высокая, то подталкивает нормально этот протокол версионировать. Что позволяет избежать отладки при апдейтах системы :)

Немного персонального опыта.
Работал и с монорепами в команде 8+ человек, работал и с полирепой в средней по размеру команде.


Имхо. Накладные расходы увеличиваются серьезно в полирепе. У нас есть makefile, который умеет инициализировать репозитории, подбрасывать симлинки на реальные инстансы кода вместо сабмодулей и много чего еще для работы. Кроме того это требует наличия метарепозитория (инфраструктурной репы), который умеет собирать все и деплоить в прод по кнопке. Все это требует вдумчивой проработки и внимания на поддержку.


Мое мнение сложилось примерно тем же, что и с микросервисами: это круто и хорошо, об этом надо задумываться, но только тогда, когда проект реально имеет несколько крупных команд поддержки/разработки и проблемы монорепы начинают мешать

Проблема в том, что когда проблемы начинают себя проявлять, разделить монорепозиторий уже скорее всего не получится по техническим, но прежде всего по идеологическим причинам (это будет выглядеть революцией по сравнению с накручиванием нового тулинга вокруг старого подхода). Именно с этой проблемой я столкнулся в своей текущей компании — проблемы видят все, но считают, что бороться надо с помощью инструментов

Одна из задач разработчика — доказать, что такая революция нужна. Особенно, в случае, когда тут команда разработчиков.


А вообще, не могу не согласиться, что чаще происходит именно так.


P. S. Накладные расходы в начале примерно такие же. Особенно, если в команде есть джуны.

UFO just landed and posted this here

Только вчера вечером задался вопросом, а Хабр вчера утром на него даёт ответ )))

Спасибо за перевод, но кажется, что исходное утверждение излишне категорично (или автор сознательно "вбросил"). Просто каждой задаче своё решение.
Монорепозиторий крупных продуктов (100-1000 разработчиков) вполне распространенное явление: ядра Windows и Linux, .NET Core (прадва, их два 2: CLR и FX, но деление относительно естественное), IntelliJ IDEA Community Edition. Chromium сидит на двух стульях (часть компонент типа V8 отдельно, но и оставшийся булыжник весьма большой). Так посмотреть, то из крупных продуктов, тех кто на git сидит (то есть JDK и Firefox на hg выпадают) — большинство сидят в монорепозиториях.
А почему?


  1. Продукт единый и нет явных причин где-то строить границу (кроме объёма репы). Ну или граница есть, и это распадается на разные продукты.
  2. Это позволяет перекраивать верхнеуровневую структуру продукта ("одним коммитом"). Причем важно, что не только структуру кода, но и структуру команд!
  3. Это позволяет вносить связанные изменения одним коммитом. Да, все стремятся делать коммиты как можно компактнее, но они же должны быть еще и "атомарными". Если одно логическое изменение приходится делать в нескольких репозиториях, то обеспечение атомарности потом нужно дополнительно обеспечить (либо в "надрепозитории", либо в сборке и упровлении зависимостями)

Да, за монорепозиторий приходится платить: производительность, строгие правила, сложная структура. Но альтернативы для целостных продуктов могут оказаться существенно дороже.


НО! Если есть возможность раскидать продукт на слабозависимые репозитории, то, конечно, это надо сделать. В корпоративной среде пример — микросервисы, в OSS — Gnome и KDE. В этих случаях обычно зависимости и связи удобнее разрешать в сборке и поставке (не в subrtee/submodule)


ИМХО про subrtee/submodule

Я считаю, что механизм subrtee/submodule придаёт совершенно ненужную хрупкость репозиторию. Лучше задачу управления зависимостями отдавать отдельным сервисам: сборке, CI, CD.


А так вот абстрактно и вообще говорить сразу за всех "пожалуйста не надо". Тем более, что аргументация слабая и есть много скорее удачных контрпримеров.

CI, конечно, очень надёжная штука. Особенно, когда разрабатываешь на локальной машине десяток зависящих друг от друга модулей.
Это чем-то похоже на «единую ли базу знаний иметь для всего человечества или одну для каждого языка?»…
Sign up to leave a comment.

Articles