Pull to refresh

Comments 101

Чисто формально, операционные системы и IDE разработчиков тоже должны жить в том же репозитории по этой логике. Включая сам гит. Не?

На самом деле отлично работает модель слоёв. Базовый слой — ОС и стандартные утилиты, поставляемые мейнтейнером дистрибутива или тем, что заменяет дистрибутив у виндузятников. В контексте образов ОС для облаков и т.д. грань становится чуть менее явной (сами свои образа собираем), но вне зависимости от того, «кто», это отлично выделяемый слой.

Следующий слой — кастомные версии нужного нам публичного ПО. Это включает в себя как припиненые версии (потому что в 1.1.3 сломано, и мы сидим на 1.1.1), и версии с собственными патчами.

Следующий слой — публичные зависимости «нашего» софта.

Следующий слой — наши зависимости уровня утилит и полностью автономных сущностей.

Дальше «наши библиотеки» общего пользования.

И уже можно делать монорепозиторий из всего остального.
Так какую структуру репозиториев предлагаете? Как я понял, не единый общий монорепо на все, а коллекцию таких репозиториев среднего размера.
Я ж говорю, слои. Это не не уровне гита даже, потому что нижние слои часто вообще не имеют исходного текста в привычном виде. Это слои инфраструктуры. В целом, это гигантский топик, базовые уровни я описал сверху.

Где-то тут ещё системы управления конфигурациями (а у них там своя система с переиспользованием кода — роли/cookbook'и), и вся инфраструктура CI/CD (сервер, на котором лежит монорепа, управляется системой управления конфигураций, которая лежит где? А код для этого сервера, условный гитлаб, откуда ставится?).
Ну есть же еще самый главный аргумент в поддержку монорепозиториев — он позволяет сделать рефакторинг по всей кодовой базе в один коммит! На самом деле, нет. Как было упомянуто в оригинальной статье, из-за ограничений, которые накладывает деплой.
Часто деплой не накладывает ограничений (это, например, характерно для заказной разработки), так что легко просматриваемый reviewer и собираемый build-сервером единственный атомарный PR — действительно существенный плюс.

P.S. В названии статьи и тексте потерялось «в git».
Ну есть ещё софт, который работает 5*8 и обновляется по выходным с даунтаймом.
Это не отменяет того, что я написал, что специфика вашего деплоя такова, что не накладывает на это ограничений. Что же, вам повезло, для вас этот недостаток неактуален.

Т.е. вы разрабатываете проекты на заказ в общем монорепозитории вашей компании, где хранятся и все разрабатываемые сейчас, и уже готовые заказы? А исходники этих проектов вы заказчикам отдаёте? Как?

Ну как, копируют в папочку и нарезают на диск :)
Между прочим, папочка и на диск (или usb flash drive) — это единственный верный с точки зрения гос. органов способ передачи интеллектуальной собственности. Ну, естественно, еще акты, закрывашки и прочее… Это же Россия!
В мое время распечатывали исходники в 4х экземплярах и сшивали :)
Что бы жить без моонрепы нужны интсрументы, а их или нет, или всем просто лень. И так сойдет. А потом уже поздно что-то менять.
Мне казалось посыл статьи как раз в том, что чтобы жить в монорепе, нужны инструменты.

С полирепой отлично живется, вроде как, инструментов море.
>> Лично у меня часто бывают ситуации, когда хочется склонировать проект в соседнюю папку, поковыряться в нем, а затем удалить
git worktree
Фуры не нужны, ведь всё можно перевезти в багажнике легковушки, просто их понадобится много.

А по делу — основным минусом полирепозиториев является невозможность быстро обновиться. В худшем же случае в какой-то момент невозможно использовать одновременно библиотеки A и B, потому что они обе зависят от библиотеки C, только разных версий, и конечно же в итоговой программе такой зоопарк не соберётся.

Я сам вообще не далеко не фанат монореп, но говорить о том, что набор независимых репозиториев существенно лучше — это самообман. И чем больше команд, тем больнее кушать этот кактус.

Видел интересный (и правильный) подход к решению проблемы — https://github.com/google/cargo-raze. Оно по constraints всего дерева зависимостей Cargo.toml старается сгенерировать общий Cargo.lock (список версий библиотек) такой, чтобы удовлетворить всех.

Ну так maven делает такой резолв версий зависимостей уже примерно лет 100. Причем политику можно задать, или для конкретной библиотеки разрулить руками и зафиксировать версию.
Но в той ситуации, что я описал, оно просто скажет «такое невозможно собрать», счастья вам от этого не прибудет.
А как вы в монорепе сделаете, чтобы А и Б зависели от разных версий Ц? Точнее, вы сделаете, только непонятно, чем тут монорепозиторий помогает? Будет ровно такой же конфликт транзитивных зависимостей, который нужно решать.
Тем, что он вам не позволит в библиотеках А и Б завязаться на разные версии Ц? Да позволит, куда денется. И точно также вы узнаете об этом в самый последний момент.
Очевидно, A и B в этом случае просто физически не могут зависеть от разных версий C, ведь C может существовать в репозитории только в одной версии в каждый момент времени, и такой проблемы не существует.
Решается элементарно копипастой.
За это надо по рукам бить, сильно.
UFO just landed and posted this here
2. Внести обратно-совместимые изменения в С. Чтобы все могли пользоваться и старой версией и новой. Ничем не отличается от полирепы.
В полирепе можно, если очень надо, внести обратно-несовместимые изменения, бампнув мажорную версию. А клиенты A, B, ...Z будут переходить уже по мере надобности и сил. А вот в монорепе да, копипаста… Ну или забить, и *не* вносить изменения (или делать это годами)…

А клиенты A, B, ...Z будут переходить уже по мере надобности и сил.

К сожалению, это означает «никогда», и срочное обновление из-за какого нибудь бага будет ооооочень болезненным. Да ещё и поддерживать старые мажорные версии придётся годами, потому что у всех планы, продакшен сломается и т.д. Это из собственного опыта, если что.
Разработчику А ничего не надо, С вообще развивается другими людьми. И вот это проблема: они то библиотеку развивают, но ни разработчики А, ни разработчики B обычно такие изменения не сильно прям хотят, им базовых фичей хватает с головой. И они ни в варианте с монорепой, ни в варианте с полирепами ничего обновлять не хотят и, следовательно, не обновляют. В варианте с монорепой в итоге за совместимостью и обновлениями голова болит у разработчиков C, а вот при полирепах только административными мерами.

Внезапно, про боль и проблемы полиреп и монореп я знаю не понаслышке как раз по опыту работы в Яндексе :) Так что я знаю, что тут происходит, и какие проблемы есть у действительно больших проектов, а не в репах на пару десятков человек.
Ага, главное чтобы у разработчика C голова от боли в конце-концов не лопнула.
И чтобы новый разработчик C не застрелился, разгребая тонны костылей «обратной совместимости» чтобы не дай бог ченить не сломать. И чтобы этот разработчик не «понаписывал» в исходниках A..Z, ведь контекста он не знает…
Тоже не идеал на самом деле.

Внезапно, про боль и проблемы полиреп и монореп я знаю не понаслышке как раз по опыту работы в Яндексе
А я знаю по опыту работы в гугле, и?
Ну, давайте про боли монореп. Больше кейсов, больше интересных решений, больше велосипедов. Расскажите, пожалуйста, если это, конечно, не нарушает NDA. Хотя можно писать и в общем — за это точно никого не побьют, а только скажут спасибо.
Да всё по классике: свой тулинг, тяжело с контрибами жить, статическая линковка, не гит (хотя это решаемый вопрос, в MS вот зафиксили же).
Плюсы: статическая линковка, воспроизводимость сборок (вот это очень хорошее свойство), нормальный поиск и возможность глобального рефакторинга, отсутствие ада зависимостей от минорных версий. Пожалуй, сюда же можно написать и тулинг: CI/CD получаешь бесплатно.

В общем, для плюсов/го/раста/etc работает относительно неплохо, для питона так себе, для ноды вообще всё сложно. Базел не пробовал, так что про него особо ничего сказать не могу. В гугле/фб не работал, а на предыдущем месте монорепа была для одного большого монопроекта, там вариантов не было особо.
Ну а если Ц — это сторонняя библиотека?
UFO just landed and posted this here
И как монорепа решает такую проблему? Просто интересно, как относится резолв зависимостей и прочие депенденси хеллы к системе контроля версий.

Я предполагаю, что при работе в монорепе органически появляется требование, что нужно использовать именно те версии библиотек, которые в ней есть. Это же и косвенная причина, почему все зависимости инжектируются в это монорепо (т.е. все 3rd party библиотеки туда втягиваются и фиксируются). Т.е. условно сделали сервисы А и Б. Они оба зависят от В. Переписали А, оно потянуло новую версию В. Сборка и тесты Б сломались. Пришлось переписывать Б на новую версию В. И так далее.

Казалось бы — мы пытаемся сделать проще и дешевле разработку, а получается ровно наоборот.
UFO just landed and posted this here
Ну, может тем, что всегда есть только последняя, крайняя версия репозитория (ну, и набор версионированных артефактов где-то сбоку)? И не нужно думать о матрице совместимости (я про нее тут упомянул).
UFO just landed and posted this here
Альтернатива — в полирепах в принципе нету возможности ограничить использование старых версий. Я видел как варианты с использованием собранных артефактов (deb-пакеты, так уж сложилось, что я в основном касался мира c++ разработки под linux), так и сложные конструкции c git submodules. Во всех этих случаях всё заканчивалось тем, что все в итоге забивают на обновление какой либо библиотеки, количество изменений постепенно растёт, и потом обновление, связанное с каким нибудь security фиксом становится невероятной болью.

И нет, невозможно все эти библиотеки превратить в микросервисы, т.к. это банально медленно. Локальный вызов стоит сотни микросекунд, сетевой — единицы миллисекунд, как минимум, а 99 процентиль — десятки и сотни миллисекунд, + он всегда может не уложиться в таймаут для конкретного запроса.
UFO just landed and posted this here
Я повторю еще раз вопрос — 1. почему два проекта A и B будут обновляться дольше, чем стопицот проектов из полирепы.

Потому что в монорепе обновление — это вопрос технический, надо взять и поменять в 100500 местах код, а в полирепах — административный, надо заменеджить каждую команду обновить свой код на новую версию, и пока они не обновятся — поддерживать 2, 3 мажорных версии и чинить в них баги параллельно. Вы же не можете самовольно решить, что не будете чинить баги в библиотеке, из-за которой вот сейчас лежит прод, правда?
2. Как относится резолв зависимостей и прочие депенденси хеллы к системе контроля версий.

В случае монорепы всё это не нужно, т.к. именно сборка делается из транка. Я подразумеваю, что монорепа == trunk based development.

Безусловно, это не решение всех проблем, но тут уже вторую статью все в комментариях говорят, что монорепа — это адище, а от большого количества реп волосы становятся мягкими и шелковистыми, при этом с проблемами полиреп в проектах с большим количеством команд не сталкивались. Вот всё далеко не так просто, и гугл/фб/яндекс/мс не от хорошей жизни на монорепах сидят.
UFO just landed and posted this here
И собственно монорепы используют в основном компании, которые пишут свои велосипеды для всего, включая большую часть инструментов разработки.

Это прям отличное описание политики Яндекса и Гугла. Мелкие компании (=стартапы) возможности строить свои велосипеды на каждый чих не имеют. И им приходится пользоваться сторонними продуктами (т.е. встает задача фиксации версий этих самых сторонних продуктов и далее поддержания их в актуальном состоянии)
Но если просто поменять код — то и в полирепе сделайте то же самое. Выкачайте 100500 репозиториев и поменяйте все места. Затем запушьте. В чем проблема?

А как вы их найдёте то? Сможете найти на гитхабе, например, всех пользователей folly?
Вы владеете кодом всех проектов в кашей компании? Тестировать, ревьюить, выкатывать, иметь ролбек план, делать все эти ваши сини-зеленые развертывания не надо? Странно слышать от руководителя яндекса что обновление — это «поменять код». Поменять код это дай бог треть работы всей. Код еще надо проревьюить, оттестировать, выкатить, мигрировать данные и т.п. Не говоря уже про то, что у вас не будет владения кодом для всех 100500 проектов. А значит — «надо заменеджить каждую команду обновить свой код на новую версию». Только одновременно.

Представьте себе, что это минорное изменение, которое не требует изменения кода. Тестирование и деплой в любом случае выполняются в соответствии с релизным циклом каждого компонента. Зато вы хотя бы получите автоматический запуск тестов для всех зависимых проектов и увидите, что своим изменением вы ничего не сломали.
А зачем? Это делается откатом нововыкаченного сервиса. Одного, а не 100500 который вы обновили. А если вы чините багу в библиотеке в то время как лежит ваш сервис на проде, то вы либо ждете пока ваш хотфикс затестят, либо имеете нехилый шанс положить остальные 100499 сервисов.
И да, в рассматриваемом примере как раз таки монорепа мешает.

Это если баг свежий, если он там 5 лет живёт и начал триггериться только сейчас, как это было с високосной секундой в ядре linux, например — то откатываться некуда.
Я сталкивался. И когда в гугловом подразделении работал, и на прошлом месте работы в дойче банке (это если что, к вашему замечанию, что дескать в яндексе действительно большие проекты, а у остальных по 20 человек).

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

Если бы для полиреп это были решенные проблемы — то dependency hell бы не существовало.
И собственно монорепы используют в основном компании, которые пишут свои велосипеды для всего, включая большую часть инструментов разработки.

Факт. Но он не подтверждает утверждение, что не надо использовать монорепы.
UFO just landed and posted this here
Пример с фолли был гиперболой для рабочей ситуации какой-то компании, код которой хранится в наборе гит реп в модном корпоративном гитхабе, битбакете или ещё как либо, сама фолли же — та самая библиотека С, которую вы меинтейните, внесли туда свои изменения и хотите, чтобы они до всех доехали. Для этого можно
  • не делать ничего, через какое-то время это приведёт к тому, что попросят сделать хотфикс, причём в старой версии — потому что текущая слишком далеко убежала вперёд, а баг вот сейчас и откат на предыдущую версию не поможет
  • найти всех пользователей и сделать PR в их код/сборочные зависимости, чтобы они перешли на новую версию, а для этого надо найти всех, кто это библиотеку использует

Монорепа очевидно не позволяет выбрать первый вариант, и существенно облегчает второй. Надеюсь, теперь пример стал понятен?

Т.е. всех проектов использующих библиотеку фейсбука, я верно понимаю?

Конечно. Всех, что разрабатываются в вашей компании.

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

Ага, и ещё замечательная пара пакетов libcurl4-gnutls-dev и libcurl4-openssl-dev, которые «инфицируют» дерево зависимостей — если хотя бы в одном месте слинковались с libcurl4-openssl-dev, то все-все-все остальные библиотеки в рамках этого бинарника ни в коем случае не должны быть слинкованы с libcurl4-gnutls-dev. Это то, что сходу в голову пришло. Для обновления gcc надо пересобрать ВСЁ, т.к. библиотеки становятся бинарно несовместимыми. Все живут конечно, пока маленькие, как только появляется несколько десятков библиотек с активной разработкой, так появляются проблемы с взаимной совместимостью, завязками на минорные версии и т.д.

Да вполне — если ваша контора не готова выделить отдельную команду чтобы писать для себя системы сборки, версионирования, индексации и прочий тулинг — то монорепа не нужна.

Но не обязательно писать свой — можно взять Bazel, как это сделали Dropbox, Uber и SpaceX.
Монорепозиторий на всю организацию — зло
Репозитории на каждый отдельный маленький компонент (вроде результатом сборки каждого репо должен быть только один артефакт) — зло, правда, меньшее.
Истина где-то посередине. Видимо, оптимально, когда есть набор проектов, которые существуют в организации. И для каждого проекта выделяется отдельный монорепозиторий, из которого он и собирается. Всякий внешний стафф (тулинги, служебные образа) — можно загонять или в отдельные репозитории, или в отдельный монорепозиторий.
Вот тогда и будет счастье.
В случае же кучи микрорепозиториев вы обрекаете себе на ад микроменеджмента зависимостей между ними.

p.s. самая боль с монорепо — это если есть внешние подрядчики (делают какие-то микросервисы) или внешние потребители кодовой базы (но им не нужно «светить» все содержимое репы) и нужно как-то синхронизировать работу с ними.
Никто не утверждает, что в репозитории должен лежать ровно один микросервис и все. В мою бытность использования полирепозиториев мы прекрасно складывали семейство тесно связанных микросервисов в один репозиторий.
Я верю, вот и пытаюсь сматчить свой опыт и свои соображения.

Касательно монорепо еще момент. Мне кажется, что инструмент git и все надстройки над ним (github/gitlab) вообще не про монорепо. От слова совсем. git прагматично решал одну конкретную задачу — задачу г-на Торвальдса по разработке ядра. Но так уж получилось, что все остальные системы управления версиями оказались не очень пригодными к промышленной эксплуатации (ну, может кроме hg, который все еще популярен в определенных кругах). Или мучения Microsoft, которым пришлось прикручивать отдельный слой файловой системы, что git нормально работал на их объемах кода — GFVS. Почитать, можно тут:
www.nixp.ru/news/14046.html
en.wikipedia.org/wiki/Git_Virtual_File_System
github.com/Microsoft/VFSForGit
Это правда, в этом и проблема, что такие инструменты как GitHub предназначены прежде всего для маленьких команд, коих сейчас огромное число. И так почти со всеми инструментами. И это неспроста — это диктует рынок.
Совет ровно один — стремитесь иметь репозиторий как можно меньшего размера.

Один файл — один репозиторий!

Один байт — один репозиторий.
Кстати, так можно радикалько снизить их количество благодаря переиспользованию.
А вообще, так выглядит 90% JS-библиотек

если есть внешние подрядчики

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

А в любой и не надо делать доступ.


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

Сами патчи — можно накладывать git'ом, но их нужно заранее готовить.


К тому же, в рамках парадигмы github & gitlab выгоднее это все производить через fork основного репозитория и разработчики шлют merge request. Понятно, что это тоже толкает не на укрупнение репозиториев, а на умельчение (чтобы не показывать лишнего).

В случае же кучи микрорепозиториев вы обрекаете себе на ад микроменеджмента зависимостей между ними.

Я работал в парадигме share-nothing, там такой проблемы нет совсем. Т.к. зависимостей между микросервисами нет. А если сервисы тесно связаны, их нужно хранить вместе.
Я работал в парадигме share-nothing, там такой проблемы нет совсем.

Смотрите. У Вас есть продукт. Он состоит из микросервисов. Очевидно, что микросервисы взаимодействуют друг с другом по публичному API (HTTP, REST, protobuf etc.). И не все комбинации версий микросервисов жизненноспособны. Поэтому важно, чтобы продукт был консистентным — держать эту матрицу совместимости где-либо. В случае кучи микрорепозиториев приходится эту интеграционную информацию выносить в отдельный репозиторий для интеграции всего. А тогда, получается, можно было сразу все пихать в монорепу.
А если сервисы тесно связаны, их нужно хранить вместе.

К вопросу связанности. Можно решить и не через монорепу, а через механизмы git по включению кода из разных репозиториев друг в друга. Те же submodules. Они не идеальны, но отчасти решают задачу.
В целом вы правы, но при подходе share nithing можно вообще ничего не хранить — каждый сервис содержит свою актуальную swagger-спецификацию, которую клиенты используют и обновляют.
Я хочу отметить, что если разговор о больших компаниях, то чаще всего отдельные сервисы разрабатываются отдельными командами. Поэтому все равно, если вы решите изменить API своего сервиса, вы не сможете переписать код всех клиентов, просто потому, что вы его не знаете и не владеете им. Поэтому, вы просто сообщаете другим командам, что у вас появились новые методы в API, но оставляете старые как deprecated.
А вообще ещё лучше делать все изменения обратно совместимыми. Если у вас API публичный, вы не владеете кодом клиентов и не можете заставить их его обновить, у вас собственно и нет других вариантов.

Не так важно как разбит код, но вот моносборка для C++, Go, Rust, Haskell — это must have, без неё очень больно жить. Отладочные символы, кросскомпиляция, профилирование, инструментирование, LTO, compile_commands.json, да и просто корректная инкрементальная сборка — всё это нормально работает только тогда, когда все зависимости бинарника собирает одна тулза. Вроде как Bazel так умеет — несколько репозиториев, но сборка центральная.

Достаточно воспользоваться source-based менеджером зависимостей.
С++ это вообще отдельная боль.
Остальные попроще, т.к. появились попозже и, соответственно, уже имеют разные механизмы сборок и разные механизмы управления зависимостями (на уровне экосистемы языка и самого языка).
CTO из Chef написал свой ответ Monorepo: please do!.. В своем ответе он утверждает, что «главное в монорепо, это то, что он заставляет разговаривать и делает недостатки видимыми».

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

Справедливости ради, гемморой — весьма эффективный катализтор роста культуры общения.
Я правильно думаю, что большая часть проблем (будь то моно- или поли-) репозиторий возникает из-за следующих факторов:
1. Отсутствие нормальной декомпозиции кода (читай, стремная архитектура с высокой запутанностью между проектами без четких границ этих самых проектов)
2. Отсутствие людей, которые хотят/могут заниматься разделением и рефакторингом взаимодействия проектов внутри компании?
Думаю, что это может быть связано, но далеко не всегда. Но в оригинальной статье автор говорит о том, что монорепозиторий провоцирует плохую архитектуру и отсутствие декомпозиции.
Основная причина, по которой я предпочитаю монорепозитории — атомарные коммиты. У нас часто бывает так, что фича требует изменений в нескольких компонентах (скрипт миграции БД, пара правок на бэкенде, еще пара на фронте, документация и т.д.) — с другими подходами типа git submodules или подгрузкой зависимостей из пакетов синхронизация и ревью таких изменений превращаются в адище.
Что у вас происходит, когда вы «атомарно» выкатываете новое апи, а пользователь вот прямо в данный момент заполняет огромную форму в старом клиенте?
Предметная область позволяет на определенное время запретить новые сессии, дождаться завершения всех текущих (они ограничены по времени) и накатить миграцию.
Основная причина, по которой я предпочитаю монорепозитории — атомарные коммиты.
Атомарные коммиты — миф. Нет, ну конечно, если у вас «огромаднейший» монорепо, в котором целый 1 бекенд, целый 1 фронтенд и да еще доки с миграциями в придачу — тогда все работает норм…

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

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

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

А чем полирепозиторий отличается от различных Depot в монорепозитории Perforce? Для svn есть sparse checkout, очень полезна штука.


А как же выкладывание в open source? Легко: p4-git; git format-patch.

Расскажите про Perforce побольше, пожалуйста. Дело в том, что когда-то давно альтернатив SVN, Rational ClearCase и MS SourceSafe ничего не было. И жизнь была болью. А теперь, когда есть phabricator, git (+github, gitlab), mercurial & co — вроде жизнь бьет ключом, но и необходимость этих энтерпрайз продуктов вроде бы и исчезла.

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


Выглядит как набор утилит, собственно сервер, различные клиенты, сервер для code review и много чего ещё, что наверное кто-то использует. Какие плюсы?


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

Знаете, я пока профита относительно gitlab не вижу. Gitlab же можно и бесплатно использовать. И самое главное — в нем можно строить пайплайны для сборки и развертки приложений… Т.е. по факту инвестируешь только время сотрудника (копейки) и вычислительные ресурсы (тоже при грамотном подходе копейки).
А за коробку вроде той, что пользуетесь Вы — нужно отваливать денег несколько раз.
Для организации размером «100+» нет уже ничего бесплатного. У вас уже точно будут несколько сотрудников, занимающихся gitlab, CI и прочими вещами. Вполне может быть, что начиная с некоторого уровня затрат, становится дешевле покупать готовое решение. А начиная с ещё более высокого уровня — писать собственное.

Free software — там «free as in freedom». Бесплатности Столлман не обещал.

Да, насчёт бесплатности — ценник на gitlab все же конский

Я про это и пишу, если внимательно посмотрите.
А энтерпрайз подписка на гитлаб — ну, да, стоит денег. Но это подписка, с разными уровнями стоимости. Т.е. бизнес может решить, что его удовлетворяет больше в текущий момент времени. А коробка — они и в Африке коробка. Инвестируете единовременно, а потом если не продлите, то можете лишиться обновлений. Или вообще функционала

Я не знаю, во сколько нашей организации обходится perforce. Там вряд ли коробка, там скорее всего похожие условия. Я на несколько уровней отстою от тех, кто принимает решения по этому вопросу.

Вот так выглядит история коммитов в моем репозитории
Так это же легко исправляется! Вот вы сами привели ссылку на сайт «trunkbaseddevelopment»…
Trunk… Based…
Так что просто не нужно делать веток! И история будет красивой и ровной :)
Ха, а мы делаем squash&merge, все ветки на картинке — это временные фича-бранчи :)
Мастер-то, ясно дело, линейный (почти:)
Спасибо, интересная статья и отдельное спасибо за конкретные цифры.
А все же, почему количество воспринимается как что-то, зависящее от количества разработчиков и что-то, несущее накладные расходы в принципе?

Доведем идею до абсудра: вот у вас в репозитории есть код приложения. И, например, в коде есть множество не связанных классов\пакетов\не важно. Свой домашний класс для работы с UUID, собственная имплементация json-сериализатора, коими нынче принято бороться со скукой в определенных кругах. И таких вот пакетов, скажем, 20.

А потом возьмем и разобьем все это дело на 21 репозиторий. В первом — основной код, и вот таких вот 20 либ. Чтобы ими пользоваться используется просто местный менеджер зависимостей для вашего ЯП — go mod, cocoapods, npm, cargo, вот эти ребята.

Где конкретно здесь появляются неудобства и дискомфорт? И как они изменяются при изменении количества реп с 1 до 100?
А зависит от Б, который зависит от Ц, который зависит от Д. Надо проверить как поведёт себя А с новой Д. И понеслось: собери Д, опубликуй под новой уникальной версией, обнови его версию в Ц, закоммить, повтори всю цепочку ещё 2 раза.
Не могу плюсовать, карма зло.

Да, хорошо, т.е неудобства появляются, когда древо зависимостей имеет глубину больше двух. Принято. Это основное неудобство в приведенной ситуации?
Да вообще неудобно ходить по 20+ репозиториев. Гипотетически можно сделать интеграционную репу, которая умеет все выкачивать (submodules, subtree), но тогда возникает вопрос изменения версий каждого компонента.
Да не нужно вам ходить по репам, в больших компаниях все равно у каждой команды свой сервис. В лучшем случае вам понадобится ваш репозиторий и, возможно, парочка соседних для интеграционного тестирования.
А я чем Вам противоречу? Выше же предлагают декомпозировать до состояния «одна репо -один артефакт (один микросервис)».
Я уж не говорю, что предположим, что Вы представляете группу билд или релиз инженеров, которые натягивают шаблоны сборки на все проекты — тогда нужен доступ ко всему.
Нельзя просто так взять и сказать, что монорепа — фуфло, а полирепа — кул. Для каждой и задачи и проекта и архитектуры и ситуации свои подходы. Сваливать весь код, конфиги и т.п. компании в одну репу — абсурд, но и дробить на сотни мелких репозиториев — тоже. Истина где-то по середине, с зависимостью от внешних факторов. Монорепа удобна для одного или нескольких проектов с десятком сервисов, которые тесно взаимосвязаны между собой, но должны быть отдельными сервисами. Нет смысла в репозиторий, в котором лежит, например, код фронт-энд отрисовки какой-нибудь карты на канвасе, вливать код бэк-энд межсервисного общения. Они никогда не будут взаимодействовать. Универсального подхода нет, всё нужно делать с умом.
Про ум все верно сказано! Это в любом деле так
Нет смысла в репозиторий, в котором лежит, например, код фронт-энд отрисовки какой-нибудь карты на канвасе, вливать код бэк-энд межсервисного общения.

Это вы только что сказали, что монорепа — фуфло.


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

А подскажите пожалуйста, как называется тип репозитория, в котором лежит несколько "проектов", но не все проекты компании?


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

А подскажите пожалуйста, как называется тип репозитория, в котором лежит несколько "проектов", но не все проекты компании?

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


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

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

Ну так у них же как раз два полирепозитория разделенные признаками языка? Или я не прав?

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

На мой взгляд эти ребята все показали предельно просто.
12factor.net/ru/codebase
Ну и 300 человек на репозиторий конечно перебор по крайней мере для комерческой разработки. Опять же это хорошо разжевано но уже у basecamp в их getting real хотя конечно их подход не всех устраивает, но зато он предельно простой.
клонирование занимает больше 10-20 минут
проект индексируется в Intellij IDEA от 30 до 40 минут

Очень интересно. Я работаю с magento 2 и всегда думал что это сверхтяжелый проект с десятками тысяч файлов. Клонирование не занимает больше 1 минуты, индексация в phpsotrm менее 30 секунд.
Можно узнать сколько у вас сотен тысяч файлов? Каков ваш конфиг рабочего компьютера?
10 тысяч — это фигня.
Был момент, когда утекли исходники NT4 и Windows 2000. Ядро и user space. Написано на С, местами С++.
Ес-но, что любая IDE давится такой кодовой базой. Сложно сказать сейчас статистику по файлам, но явно есть совершенно разные требования по разбору разных языков.
У нас Typescript + Java :)
Конфиг хороший — МакБук Про.
Посмешили)) Макбук про даже последних версий мягко говоря отдыхает по сравнению с десктопными процессорами, не говоря уже про hedt с 12/16-ядерными тредриперами.
На счет typescript все понял, буду 2 раза думать если буду выбирать)
Зачем ее решать, если можно не решать?
И скорее всего мне нужен весь репозиторий (ведь если он весь собирается одним билд тулом), а не его часть

Есть еще git clone --depth 1, но он тоже не решает проблему системно.

Когда размеры репозитория переваливают за десятки гигабайт, то локально вы всё равно вряд ли что-нибудь соберёте за разумное время. В организациях работающих с такими большими кодовыми базами обычно вся сборка, тестирования и т.п. идёт на выделенных серверах. Вот у них может быть весь репозиторий, а разработчики достаточно только части, над которой он работает.
Согласен. Без всех тулзов и что немаловажно — средств, монорепо выглядит как глупая затея. Для монорепо нужнее как минимум очень стабильный и быстрый CI.
Sign up to leave a comment.

Articles