Некоторое время назад на отличной конференции maintainerati я пообщался с несколькими друзьями-мейнтейнерами о масштабировании по-настоящему больших проектов open source и о том, как GitHub подталкивает проекты к определённому способу масштабирования. У ядра Linux абсолютно иная модель, которую мейнтейнеры-пользователи GitHub не понимают. Думаю, стоит объяснить, почему и как она работает и чем отличается.

Ещё одной причиной для написания этого текста стала дискуссия на HN по поводу моего выступления «Мейнтейнеры не масштабируются», где самый популярный комментарий сводился к вопросу «Почему эти динозавры не используют современные средства разработки?». Несколько известных разработчиков ядра энергично защищали списки рассылки и предложение патчей через механизм, похожий на пулл-реквесты GitHub, Но по крайней мере несколько разработчиков графической подсистемы хотели бы использовать более современный инструментарий, который гораздо легче автоматизировать скриптами. Проблема в том, что GitHub не поддерживает тот способ, которым ядро Linux масштабируется на огромное число контрибуторов, и поэтому мы просто не можем перейти на него, даже для нескольких подсистем. И дело не в хостинге данных на Git, эта часть явно в порядке, а дело в том, как на GitHub работают пулл-реквесты, обсуждение багов и форки.

Масштабирование в стиле GitHub


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

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

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

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

  • Ваше сообщество слишком фрагментируется. Большинство контрибуторов будут просто иметь дело с кодом и соответствующим репозиторием, куда они напрямую контрибутят, игнорируя всё остальное. Им-то классно, но так значительно снижается вероятность вовремя заметить дублирующиеся усилия и параллельные решения между разными плагинами и бибилотеками. И людям, которые хотят управлять всем сообществом в целом, придётся иметь дело с кучей репозиториев, которые или управляются через скрипт, или подмодули Git, или что-то ещё худшее. К тому же, они утонут в пулл-реквестах и проблемах, если на что-нибудь подпишутся. Любая тема (может, у вас общий инструментарий для сборки билдов или документация, или что угодно ещё), которая не вписывается идеально в разделённые репозитории, становится головной болью для мейнтейнеров.
  • Даже если вы заметили необходимость рефакторинга и совместного использования кода, здесь возникает больше бюрократических препятствий: сначала нужно выпустить новую версию ключевой библиотеки, затем пройтись по всем плагинам и обновить их, и только потом, может быть, вы сможете удалить старый код в библиотеке совместного доступа. Но поскольку всё сильно разбросано вокруг, вы можете и забыть о последнем шаге.

    Конечно, всё это требует не такой уж большой работы, и многие проекты отлично справляются с управлением. Но здесь всё равно требуется больше усилий, чем простой пулл-реквест в единый репозиторий. Очень простые операции рефакторинга (как простое совместное использование единственной новой функции) происходят реже, и за долгое время такие издержки накапливаются. За исключением тех случаев, когда вы по примеру node.js создаёте репозитории для каждой функции, а затем по сути меняете Git на npm в качестве системы управления исходным кодом, и это тоже кажется странным.
  • Комбинаторный взрыв теоретически поддерживаемых разных версий, которые становятся де-факто неподдерживаемым. Пользователям приходится осуществлять интеграционное тестирование. А в проекте всё сводится к одобренным («благословенным») сочетаниям версий, или по крайней мере такое декларируется де-факто, поскольку разработчики просто закрывают сообщения о багах словами «пожалуйста, сначала обновите все модули». И снова, это означает, что у вас фактически монорепозиторий, разве что не на Git. Ну, только если вы используете подмодули, и я не уверен, что это считается Git...
  • Болезненная реорганизация при разделении общих проектов на подпроекты, поскольку вам нужно реорганизовать репозитории Git и то, как они разделяются. В едином репозитории смена мейнтейнера сводится к простому обновлению файлов OWNER или MAINTAINERS, а если ваши боты в порядке, то новые мейнтейнеры получат теги автоматически. Но если для вас масштабирование означат разделение репозиториев на разрозненные наборы, то любая реорганизация будет настолько же болезненна, как и первый шаг от единственного репозитория к группе разделённых репозиториев. Это означает, что ваш проект слишком надолго застрянет на плохой организационной структуре.

Интерлюдия: зачем существуют пулл-реквесты


Ядро Linux — один из нескольких известных мне проектов, который не разделён таким образом. Прежде чем мы рассмотрим, как он работает (ядро — это гигантский проект и он просто не может работать без некоторой структуры подпроектов), мне кажется, интересно посмотреть, зачем в Git нужны пулл-реквесты. На GitHub это единственный способ разработчикам внести предложенные патчи в общий код. Но изменения в ядре приходят как патчи в почтовом списке рассылки, даже через долгое время после внедрения и широкого использования Git.

Но уже первая версия Git поддерживала пулл-реквесты. Аудиторией этих первых, достаточно сырых, релизов были мейнтейнеры ядра, Git написали для решения мейнтейнерских проблем Линуса. Очевидно, Git был нужен и полезен, но не для обработки изменений от отдельных разработчиков: даже сегодня, а тем более тогда, пулл-реквесты использовались для обработки изменений целой подсистемы, синхронизации отрефакторенного кода или схожих сквозных изменений между различными подпроектами. Как пример, сетевой пулл-реквест 4.12 от Дэйва Миллера, представленный Линусом, содержит более 2000 коммитов от 600 разработчиков и кучу слияний для пулл-реквестов от подчинённых мейнтейнеров. Но почти все патчи сами по себе представлены мейнтейнерами и выбраны из почтовых списков рассылки, а не самими авторами. Такова особенность разработки ядра, что авторы в основном не коммитят патчи в общие репозитории — и вот почему Git отдельно учитывает автора патча и автора коммита.

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

Масштабирование способом ядра Linux


На первый взгляд, ядро выглядит как единый репозиторий, где всё в одном месте в репозитории у Линуса. Но это далеко не так:

  • Почти никто не использует основной репозиторий Линуса Торвальдса. Если у них и работает что-то из апстрима, то обычно это одно из стабильных ядер. Но намного более вероятно, что у них ядро со своего дистрибутива, где обычно есть дополнительные патчи и бэкпорты, и оно даже не хостится на kernel.org, это совершенно другая организация. Или у них ядро от своего аппаратного вендора (для SoC и почти для всего, связанного с Android), которое часто значительно отличается от всего, что хостится в одном из «основных» репозиториев.
  • Никто (кроме самого Линуса) не разрабатывает ничего для репозитория Линуса. У каждой подсистемы, а часто даже у крупных драйверов, есть собственные репозитории Git, с собственными списками почтовой рассылки для отслеживания патчей и обсуждения проблем полностью изолированно от всех остальных.
  • Работа между подсистемами производится поверх дерева интеграции linux-next, которое содержит несколько сотен веток Git из примерно такого же количества репозиториев Git.
  • Всё это сумасшествие управляется через файл MAINTAINERS и скрипт get_maintainers.pl, который для каждого данного сниппета кода может сказать, кто мейнтейнер, кто должен проверить код, где находится правильный репозиторий Git, какие использовать списки рассылки, как и где сообщать о багах. Информация основана не просто на расположении файла. Также производится анализ шаблонов кода для проверки, что кросс-подсистемные темы вроде обслуживания device-tree или иерархии kobject hierarchy обрабатываются правильными экспертами.

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

  • Совершенно легко провести реорганизацию, выделяя вещи в подпроект — просто обновите файл MAINTAINERS, и готово. Остальное немного сложнее, чем должно быть, потому что вам может понадобиться создать новый репозиторий, новые списки рассылки и новую bugzilla. Это просто проблема UI, которую GitHub элегантно решил классной маленькой кнопкой fork.
  • Очень, очень просто перевести обсуждение пулл-реквестов и проблем между подпроектами, вы просто изменяете поле Cc: в своём ответе. Также намного проще координировать работу между подсистемами, поскольку один пулл-реквест можно направить в несколько подпроектов, при этом ведётся только одно общее обсуждение (поскольку теги Msg-Ids: в тредах списка рассылки одинаковы для всех), хотя сами письма архивируются в куче разных архивов списков рассылок, проходят через разные списки рассылки и лежат в тысячах разных почтовых ящиков. Простое обсуждение тем и кода между подпроектами позволяет избежать фрагментации и так легче заметить, где будет полезно использование общего кода и рефакторинг.
  • Работа между подсистемами не нуждается в каком-то танце с релизами. Вы просто изменяете код, который весь у вас в едином репозитории. Заметьте, что это намного эффективнее, чем возможно в раздельных репозиториях. В случае действительно агрессивного рефакторинга можно просто разделить работу между несколькими релизами, например, когда есть так много пользователей, что вы можете просто изменить их всех сразу, не вызывая слишком больших проблем с координацией.

    Огромное преимущество того, что рефакторинг и обмен кодом стал проще — не нужно тащить с собой кучу легаси-мусора. Это детально объясняется в документе об отсутствии бреда со стабильными API.
  • Ничто не мешает вам создавать собственные экспериментальные дополнения, что является одним из ключевых преимуществ системы с множеством репозиториев. Добавили свой код в свой форк и оставили его там — никто никогда не заставит вас запушить код обратно или запушить его в один общий репозиторий или даже передать в основную организацию, просто потому что нет центральных репозиториев. Это действительно хорошо работает, может и слишком хорошо, свидетельством чему миллионы строк кода вне веток в различных репозиториях аппаратных вендоров Android.

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

Это выглядит как фильм ужасов о монорепозитории!


Да и нет.

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

Но если посмотреть ближе, такая модель очень, очень далека от единого репозитория Git. Одна только upstream-подсистема и репозитории драйверов уже дают вам несколько сотен. Если посмотреть на всю экосистему целиком, включая аппаратных вендоров, дистрибутивы, другие ОС на базе Linux и отдельные продукты, вы легко насчитаете несколько тысяч основных репозиториев и ещё много-много дополнительных. И это без учёта репозиториев Git чисто для личного использования отдельными разработчиками.

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

Примеры, пожалуйста!


Прежде чем я начну объяснять, почему GitHub не способен в данный момент обеспечить такой рабочий процесс, по крайней мере, если вы хотите сохранить преимущества GitHub UI и интеграции, нужно посмотреть на некоторые примеры, как это работает на практике. Если вкратце, то всё делается через пулл-реквесты Git между мейнтейнерами.

Простой случай — это прохождение изменений через иерархию мейнтейнеров, пока они в конце концов не осядут в дереве там, где нужно. Это легко, потому что пулл-реквест всегда идёт из одного репозитория в другой, так что его можно провести с нынешним GitHub UI.

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

Слияние отличается от рассмотрения патча. Здесь уже выбирается одна из подсистем как основная, она получает все пулл-реквесты, а все остальные мейнтейнеры соглашаются с таким вариантом слияния. Обычно выбирают ту подсистему, которую сильнее всего затрагивают изменения, но иногда выбирают ту, в которой уже идёт какая-то работа, которая конфликтует с пулл-реквестом. Иногда создают абсолютно новый репозиторий и команду мейнтейнеров. Это часто происходит для функциональности, которая распространяется на всё дерево и не очень аккуратно содержится в нескольких файлах и директориях в одном месте. Недавний пример — дерево отображений DMA, которое пытается объединить работу, до сих пор распределённую среди драйверов, мейнтейнеров платформы и групп поддержки архитектуры.

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

В качестве примера могу привести поддержку audio-over-HDMI, в этот процесс я был вовлечён непосредственно. Она касается и графической подсистемы, и подсистемы звуковых драйверов. Одинаковые коммиты из одного и того же пулл-реквеста вошли в графический драйвер Intel, а также в звуковую подсистему.

Совершенно другой пример, что это не безумие — единственный сравнимый проект ОС в мире тоже выбрал монодерево с потоком коммитов примерно как в Linux. Я говорю о ребятах с таким гигантским деревом, что им даже пришлось написать полностью новую виртуальную файловую систему GVFS для его поддержки…

Дорогой GitHub


К сожалению, GitHub не обеспечивает поддержку такого рабочего процесса, по крайней мере, не нативно с GitHub UI. Конечно, это можно сделать просто с чистым инструментарием Git, но тогда вы возвращаетесь к патчам в списке рассылки и пулл-реквестам по почте, которые выполняются вручную. Я считаю, это единственная причина, почему сообщество разработчиков ядра ничего не выиграет от перехода на GitHub. Есть также небольшая проблема, что несколько ведущих мейнтейнеров настроены категорически против GitHub в целом, но это уже не технический вопрос. И дело не только в ядре Linux. Дело в том, что в принципе все гигантские проекты на GitHub имеют проблемы с масштабированием, потому что GitHub на самом деле не даёт им возможности масштабироваться на многочисленные репозитории, привязанные к монодереву.

Итак, у меня есть запрос только одной фичи на GitHub:

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

Простая идея, огромные последствия.

Репозитории и организации


Во-первых, нужно сделать возможными многочисленные форки того же репозитория в одной организации. Просто посмотрите на git.kernel.org, большинство их репозиториев не являются личными. И даже если вы поддерживаете разные организации, например, для разных подсистем, требование наличия организации для каждого репозитория — глупое и избыточное, оно без какой-либо необходимости до предела затрудняет доступ и управление пользователями. Например, в графической подсистеме у нас было бы по одному репозиторию для каждого тестового набора userspace, общая библиотека userspace и общий набор инструментов и скриптов, которые используются мейнтейнерами и разработчиками, это GitHub поддерживается. Но потом вы добавите общий репозиторий подсистемы, плюс репозиторий для ключевой функциональности подсистемы и дополнительные репозитории для каждого крупного драйвера. Это всё форки, которые GitHub не делает. И у каждого из этих репозиториев будет куча веток: по крайней мере, одна для работы над функциями, а другая для исправления багов в текущем релизе.

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

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

Пулл-реквесты


Пулл-реквесты нужно привязать к нескольким репозиториям одновременно, сохраняя единый общий поток обсуждения. Вы уже можете переназначить пулл-реквест на другую ветку репозитория, но не на несколько репозиториев одновременно. Переназначение пулл-реквестов действительно важно, поскольку новые участники проекта будут просто создавать пулл-реквесты к тому, что они считают основным репозиторием. Боты затем могут перетасовать их с учётом всех репозиториев, перечисленных в файле MAINTAINERS для того набора файлов и изменений, которые содержит репозиторий. Когда я беседовал с сотрудниками GitHub, то сначала предложил им реализовать это напрямую. Но думаю, здесь всё можно автоматизировать скриптами, так что лучше будет оставить это только для индивидуальных проектов, поскольку тут нет единого стандарта.

Тут ещё довольно мерзкая проблема UI, потому что список патчей может отличаться в зависимости от ветки, куда идёт пулл-реквест. Но это не всегда ошибка пользователя, ведь какой-то из репозиториев уже может применить какие-то патчи.

Кроме того, статус пулл-реквеста должен отличаться для каждого репозитория. Один мейнтейнер может закрыть его, не принимая, поскольку решили, что его примет другая подсистема, в то время как другой мейнтейнер может произвести слияние и закрыть вопрос. В другом дереве могут даже закрыть пулл-реквест как невалидный, поскольку он неприменим для старой версии или форка от вендора. Ещё веселее, пулл-реквест может пройти через слияние несколько раз, с разными коммитами в каждой подсистеме.

Баги


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

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

Вывод: монодерево, а не монорепозиторий


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

Комментарии (55)


  1. Londoner
    27.08.2017 12:46
    +18

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

    Вот тут я получил вывих мозга.


    1. khim
      27.08.2017 17:41
      +12

      Это переводчик вывих мозга получил. В оригинале речь шла о том, что в том репозитории nVidia не так много кода — в основном код для «склейки» их проприетарного «блоба» (==собственно драйвера) с ядром Linux'а, но так как оный блоб не содержит никакого кода из ядра, то код в том репозитории — это прекрасный пример того как нечто разрабатывается сторонней организацией, которая никогда даже не собиралась играть по «правилам» игры, которые устанавливают разработчики ядра.


  1. Alex_ME
    27.08.2017 12:57
    +1

    Честно говоря, немного не понял как осуществляется процесс отправки патча от разработчика к мейнтейнеру.


    1. apro
      27.08.2017 13:08
      +2

      По email. Просто вставляешь патч в письмо и отправляешь с CC в список рассылки.


      1. ctacka
        28.08.2017 02:59

        Или git format-patch


  1. Falstaff
    27.08.2017 14:31
    +5

    Может кто-нибудь сказать: почему нельзя вместо отдельных репозитариев — по сути форков — в которых ведётся работа над подсистемами, использовать ветки? Сугубо с точки зрения разделения кода. Если я правильно понял (не факт, что правильно понял — я всё ещё объят сном, сейчас мне кто-нибудь объяснит, я хлопну себя по лбу и скажу: а-а, да… пардон, я сонный), то вместо разделения проекта на модули ядро просто назначает: вот в этой копии репозитария мы работаем над сетью, а в этой над файловой системой. Потом контрибьюторы шлют изменения, майтайнеры анализируют их и возможно координируют дела со смежными форками (если изменения затрагивают несколько подсистем или ведётся конфликтующий набор изменений), потом всё идёт ещё выше большими пулл-реквестами, и в конце-концов приземляется в репозитарии Линуса. Так репозиторий один, весь код виден всем сразу, но работа организована иерархически. Поэтому мне просто интересно, не могут ли — чисто технически — долгоживущие ветки (на стороне основного репозитария) заменить отдельные репозитарии. Договориться об именовании веток (скажем, в net майнтайнер будет собирать работу для сети, а дальше в net/* уже ведутся изменения, из которых посылать патчи), должно такое работать или нет? Просто я смотрю на копии репозитариев у майнтайнеров подсистем (и опять же, скорее всего чего-то важного не вижу), и они мне кажутся такими glorified branches.


    1. apro
      27.08.2017 16:38
      +2

      По крайней мере с правами доступа проблема. Насколько я понимаю для связки типа git+ssh нельзя назначить доступ людям на основе веток. В github вроде нет таких проблем. Но с ним другая проблема, если всю работу сосредоточить в одном репозитории с ветками для мантейнеров есть большая вероятность утонуть под количеством issue и pull request, даже при наличии меток и прочего.


      1. Falstaff
        27.08.2017 16:54

        Вроде бы можно… я не уверен, но, помнится, ещё gitolite в своё время позволял назначать очень мелкозернистые права, ограничивать пространства имён веток, где и кому можно создавать ветки (например, студентам разрешить создавать ветки под lab1/*), квоты — как будто всё для этого имелось. Поправьте, если кто лучше знает.


        Ну и с issue — это уже другая проблема, я именно поэтому уточнил "… сугубо с точки зрения разделения кода", бактрекер — это уже не контроль версий. Меня интересовало, это мне чудится, или действительно такие копии репозитариев — это на самом деле такие вручную сделанные ветки. Кстати, а pull request при чём? Я имею в виду не гитхабовский pull request, а просто — почему можно формировать pull request между копиями репозитариев, но нельзя тем же способом между ветками?


        1. khim
          27.08.2017 17:37

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

          Просто Линус вдоволь насмотрелся на тему срача вокруг «committer access»а и «branch creation criteria» в разных *BSD и GCC и был принципиально против системы в которой понятие «committer access» вообще существует.


    1. khim
      27.08.2017 17:34
      +1

      Так репозиторий один, весь код виден всем сразу, но работа организована иерархически.
      Собственно git изначально был написан так, чтобы удовлетворять одному простому требованию: код, написанный Intel для поддержки ещё не выпущенных процессоров Intel (на самом деле тогда Transmeta — но неважно), должен физически находиться только на серверах Intel (с контролируемым доступом, понятно).

      В этом — смысл D в DVCS. Линус категорически отказывался пользоваться VCS, которые не удовлетворяли этому условию, а когда доступа к единственной системе контроля версий, удовлетворяющей этому условию (и при этом «промышеленной», не умирающей на проектах масштаба ядра Linux), его лишили — написал свою.

      Просто я смотрю на копии репозитариев у майнтайнеров подсистем (и опять же, скорее всего чего-то важного не вижу), и они мне кажутся такими glorified branches.
      Они и есть «glorified branches» — но с двумя важными отличиями:

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

      Оба момента для Линуса были принципиально важны.


      1. Falstaff
        27.08.2017 17:47

        Нет-нет, я понимаю саму оригинальную задумку DVCS — чтобы у каждого был полноправный репозитарий, а коммиты могли курсировать между репозитариями. (Про нюанс с проприетарным кодом Intel — вот этого не знал.) Меня интересовал сам технический вопрос, в более узком смысле — автор упомянул, что от гитхаба им нужно только более гибкое взаимодействие между форками (чтобы они трактовались как части одного проекта), вот и подумалось, что по сути-то они трактуют репозитарии как ветки. Понятно, что всё ещё потребуется возможность анонимного создания веток контрибьюторами.


      1. Ilirium
        27.08.2017 18:44

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


  1. danfe
    27.08.2017 18:14
    -1

    На GitHub [пулл-реквесты] это единственный способ разработчикам внести предложенные патчи в общий код.
    Довольно странное утверждение. Можно открыть ишью и приложить патч (я обычно так и делаю), можно дать ссылку на сторонний багтрекер или репозиторий. Часто, действительно, просят сделать pull request, но лично мне это неудобно. Иногда я иду навстречу, иногда вежливо отказываюсь, объясняя, что постоянно работать над этим кодом не собираюсь, и смысла клонировать проект только для того, чтобы сделать один-два пулл-реквеста, не вижу.


    1. SirEdvin
      27.08.2017 18:46

      Я думаю, тут смысл в том, что единственный более удобный, чем то, что уже используется сейчас. Более того, мне кажется, что формат рассылки более удобный, чем открывать issue, но это уже детали.


    1. sumanai
      27.08.2017 23:13
      +3

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


      1. bromzh
        28.08.2017 16:50

        Закоммитить локально, сформировать письмо с патчем (git format-patch), потом отправить по почте кому-нибудь (git sendmail). Например, другим разработчикам проекта. А чтобы применить изменения, сделанные другими пользователями, нужно получить письмо с патчем и выполнить git am.
        Т.е. грубо говоря, git push в удалённый репозиторий заменяется на git sendmail, а git pull на git am. При этом вариант с почтой получается p2p, т.е. изменения пользователям приходят напрямую от других пользователей.


  1. Ilirium
    27.08.2017 18:42
    +8

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


    1. prefrontalCortex
      27.08.2017 22:45
      +1

      Плюсую этого комментатора, было бы интересно изучить в деталях.
      Вот, например, в упомянутое "дерево интеграции linux-next" как всё сливается? Через subtree?


  1. MaxKorz
    27.08.2017 20:56
    +2

    Меня интересует такой вопрос — что будет, если с Линусом что-то случится? Он конечно молодой (47 лет), но люди и в 50 могут умереть, не говоря уже про несчастные случаи (авария, фен в ванну упал и т.п.). Если Линус лично принимает все изменения в мастер репозиторий и выкатывает релиз, то в случае, если он не будет в состоянии этого делать, кто будет ответственен за дальнейшие релизы? А главное, будут ли компании-производители доверять этому человеку или каждый сделает свой форк и начнется хаос?


    1. SirEdvin
      27.08.2017 21:14
      +2

      Там в целом написано. Сам по себе Linus никому не указ, у каждой компании своя ветка, так что если репозиторий чисто Linus'а больше не будет работать, существенно ничего не поменяется. Ведь по сути, ни в одном дистрибутиве Linux нет ванильного ядра.


    1. khim
      28.08.2017 01:43
      +3

      Если Линус лично принимает все изменения в мастер репозиторий и выкатывает релиз, то в случае, если он не будет в состоянии этого делать, кто будет ответственен за дальнейшие релизы?
      Я думаю вначале будет много неразберихи, но через год-два всё устаканится.

      А главное, будут ли компании-производители доверять этому человеку или каждый сделает свой форк и начнется хаос?
      А этих «форков» и сейчас… как грязи. Большинство железячников, в частности, ядро от Линуса не волнует от слова «никак» — они пользуют ядро от Android'а. А многие — и куда более древние ядра от разных компаний.

      В том-то и фишка, что ядро Линукса — это реально распределённый проект и очень многие фичи годами живут вне основной ветки. Чисто так для примера: OverlayFS в ядре Линуса появилась-таки в 2014м году. Притом что первая версия этой идеи (под названияем IFS — Inherited File System) появилась в Slackware, на минуточку, в 1993м (sic!) году.


      1. molotok-sms
        29.08.2017 22:01

        IFS напоминает Integrated file system от IBM… я сначала подумал, что IBM-овская версия появилась раньше, но погуглил — вроде как, она появилась с системы IBM i5/OS, датируемоей 2004 годом…


    1. llolik
      28.08.2017 10:15

      если он не будет в состоянии этого делать, кто будет ответственен за дальнейшие релизы?
      ИМХО кто-нибудь из основных разработчиков. Грег Кроа-Хартманн, например.


  1. firk
    27.08.2017 21:13

    Мне кажется автор статьи, за кучей текста, упустил один простой момент. Распределённый репозиторий он на то и распределённый, что не хостится в одном месте. Никто не запрещает хостить на гитхабе свой форк ядра и слать из него патчи в апстрим. Думаю многие так и делают. Никто не запрещает делать то же самое на любом другом публичном гит-хостинге, либо где-то на своём сервере.
    Каждый выбирает то что лично ему удобнее (включая Линуса, выпускающего официальные релизы со своей ветки). Очевидно, свой сервер всегда будет более гибким, чем чей-то (например гитхабовский), поэтому всегда будут те, кто эту гибкость желает использовать.
    А те, кто ВСЮ работу с кодом ведут только через один хостинг — по сути не используют распределённость, ради которой гит создавался, и с тем же успехом могли бы пользоваться свн (наверно даже удобнее, если распределённость не нужна), но выбрали гит по причине модности.


    1. SirEdvin
      27.08.2017 21:16
      +2

      Попробуйте в svn использовать какой-то git-flow и вы почувствуете боль. Реальная полезность git'а, за которую его любят разработчики, в духе "одна фича — одна ветка" и прочие штуки не зависят от того, где именно его хостить.


      1. firk
        27.08.2017 22:42

        Ну очевидно что конкретный инструмент "git-flow" был сделан для git. Но не вижу проблем реализовать ту же логику и в svn, если всё в одном репозитории на одном сервере. Есть ли для этого готовые инструменты или нет — не в курсе.


        1. SirEdvin
          27.08.2017 22:43

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


          Ну и да, как я тут почитал, в svn я не могу на локальной машине все делать и делать коммиты, а потом такой svn push. Там коммитить нужно сразу в мастер репозиторий. Так что разработчики автоматически используют преимущество git.


          1. firk
            28.08.2017 01:50

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


            git push = svn commit (перенос локальных правок на сервер)
            git commit = svn просто локальные правки, да их нельзя сортировать и подтверждать инкрементально перед отправкой на сервер, как в гите, забыл про это отличие, но по-моему оно и не особо нужно и может даже мешать лишними действиями при централизованном репозитории (хотя кому как)


            1. SirEdvin
              28.08.2017 10:27

              Но вот переключение, бранчей, например, делается дольше: https://habrahabr.ru/post/320704/


              Ну и да, возможность коммитить локально — очень полезная штука, которая позволяет забить, скажем, на временную недоступность централизованной штуки (например, gitlab.com в последнее время иногда падает).


        1. symbix
          28.08.2017 05:29
          +1

          В svn merge всегда будет болью, а если мержиться практически невозможно — никакой инструмент не поможет.


  1. Xeli
    27.08.2017 21:35

    Я не понимаю, а кто мешает сделать паралельный форк ядра на гитхабе? GPL жИ! Бери исходники и делай, не забывая форк вести под GPL. Там уже можешь плясать как тебе вздумается, хоть в стиле кантри, хоть гопак! А Линус может факами своими истыкать хоть весь ютуб, выкладывая в день по видео с факом в твою сторону! Тебя и твой форк уже будет не остановить!


    1. SirEdvin
      27.08.2017 22:46
      +5

      Потому что этот новый форк будет никому не нужен?)


      1. Xeli
        27.08.2017 23:26
        +1

        Собственно как и ванильное ядро от Линуса без допиливания, если не ошибаюсь никому не нужно кроме Патрика (который Бох, хотя может и тоже допиливают, но вроде как в Слаке ванильное ядро). Популярные дистрибутивы допиливают ядро под свои особенности на своих серверах. Но собственно никто не запрещает это делать в том числе и на гитхабе. Но как по мне свой сервер для этой задачи гораздо удобней и приятней в работе. Опять же Git распределенная система контроля версий. Можно вообще организовать бессерверную работу отправляя «диктатору» патчи по электронной почте.


    1. Sirikid
      28.08.2017 03:45
      +1

      Форк сделать можно, продолжать разработку ядра в том же стиле — нельзя. Поэтому ребята не собираются переходить на GH.


  1. symbix
    28.08.2017 06:19

    А зачем вообще разработчикам ядра фичи гитхаба? Git сделан децентрализованным и распределенным прежде всего потому, что сама модель разработки децентрализована. E-mail — тоже в достаточной мере децентрализованная штука. А гитхаб (в смысле, не репозиторий на нем, а issues и pull requests) станет single point of failure.


  1. akamensky
    28.08.2017 07:09
    -5

    Я думаю не все в курсе, а статья не упоминает, что сам Git был разработан Линусом, как раз таки специально для того чтобы хостить код ядра. Github же предоставляет достаточно урезанную по функциональности версию Git.


    1. symbix
      28.08.2017 11:01
      +2

      Это вы о чем вообще? Если про гитхабовский git-клиент — он делался для домохозяек, никто не мешает использовать обычный консольный git.


      1. akamensky
        28.08.2017 11:41
        +1

        Это я о том что Git изначально заточен под работу именно в стиле kernel. Те кто пользуется Github используют в лучшем случае 20% от всей функциональности Git'а, а остальные функции для этих пользователей выглядят сложными и часто ненужными (достаточно погуглить на англ про git-rebase, например, очень много кто не понимает разницу, или тот же cherry-pick, хотя обе функции активно используются в kernel и других масштабных проектах).


        1. Xeli
          28.08.2017 14:54
          -1

          А что есть такие которые используют github без консольного управления? Оне наверно гении у них внутре неонка.


          1. MaxKorz
            28.08.2017 15:51

            тот же webstorm позволяет клонировать репозитории, комитить изменения, делать пул реквесты, откатывать комиты, использовать stash, cherry pick и прочее и прочее через интерфейс не вводя ни одной команды.


            1. Xeli
              28.08.2017 16:15
              -2

              Это ведет к деградации. Да и все эти гуевые инструменты никогда не заменят консольные команды.


              1. MaxKorz
                28.08.2017 16:21
                +1

                это как спор «автомат или ручная коробка передач». Достаточно смелое заявление, что GUI ведет к деградации.


                1. Xeli
                  28.08.2017 16:38

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


                  1. sumanai
                    28.08.2017 16:46
                    +1

                    Это проблемы Git, а не GUI. Я использую Mercurial, где TortoiseHg предоставляет полную функциональность через GUI. И у меня никогда не было случаев, когда что-то шло не так.


                    1. Xeli
                      28.08.2017 16:53
                      -1

                      Это проблемы Git

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


                      1. MaxKorz
                        28.08.2017 17:00

                        Вы сами создаете себе проблему (используете консоль вместо GUI) и сами же ее преодолеваете (читаете книги и мануалы по использованию инструмента), в то время как остальные — живут полной жизнью и использует инструмент ради достижения цели, а не ради лозунга «gui — гавно для еретиков, консоль forever»


                        1. Xeli
                          28.08.2017 17:02
                          -2

                          Не буду спорить. Когда обкакаетесь на нестандартной задаче, тогда и поговорим.


                          1. sumanai
                            28.08.2017 17:12

                            Дайте мне такую нестандартную задачу, которую я не смогу решить через GUI моего TortoiseHg.


                            1. bromzh
                              28.08.2017 17:52
                              +1

                              Сервер без GUI, доступ к нему по ssh. Как, не прибегая к консоли, склонировать на сервер репозиторий и управлять им?


                              1. splav_asv
                                28.08.2017 23:38

                                X'ы поверх ssh?
                                P.S. сам GUI к VCS никогда не пользовался.


                              1. kireevco
                                29.08.2017 08:25

                                • Docker на Alpine Linux туда же.


                              1. sumanai
                                29.08.2017 20:35

                                А какое там заумное управление требуется? Только закачать и сливать изменения, две команды, задача вполне стандартная.


            1. symbix
              29.08.2017 01:39

              В JetBrains-овских IDE в целом сделано неплохо, но некоторые вещи удобнее делать с консоли. Я совмещаю.


              Ну и add -p там вообще нет, тикет уже 7 лет висит. Хотя вроде начались подвижки.


        1. symbix
          29.08.2017 01:33

          Это не пользователи github, а большинство пользователей git. Для мелких проектов с полутора разработчиками большего и не требуется. А если начнут работать в нормальной команде — научатся, никуда не денутся (достаточно будет один раз получить по шапке).


  1. dfuse
    31.08.2017 23:41

    Дай бог в GitLab запилят, они иногда быстрее фичи выпускают