Когда использовать git subtree?

81

Какую проблему git subtreeрешает? Когда и почему мне следует использовать эту функцию?

Я читал, что он используется для разделения репозитория . Но почему бы мне просто не создать два независимых репозитория вместо того, чтобы объединить два несвязанных друг с другом в один?

В этом руководстве GitHub объясняется, как выполнять слияние поддеревьев Git .

Я вроде как знаю, как его использовать, но не знаю , когда (варианты использования) и почему , и как это относится git submodule. Я бы использовал подмодули, когда у меня есть зависимость от другого проекта или библиотеки.

Lernkurve
источник
1
"разделение репозитория"! = "несвязанные репозитории" думайте о зависимостях в вашем репо, и вы не хотите использовать подмодули (по какой-то причине, возможно, вам не нравится, что они не прозрачны и что пути в коммитах в подмодуль не соответствует вашему пути в основном репозитории git).
cyphar
1
@cyphar: Вы говорите, что оба submoduleи subtreeболее или менее достигают одной и той же цели, включающей связанные проекты, и что единственная разница в том, что submoduleможет быть немного менее прозрачным, а обновление подмодулей - это двухэтапная операция, и что недостатком subtreeявляется то, что сообщения коммита будут смешаны между двумя проектами?
Lernkurve
1
Что ж, в некоторых случаях это не является недостатком. Например, если вам нужно разделить пополам репозиторий, в котором есть subtrees, и в зависимости была введена ошибка, вы найдете точную фиксацию в тойsubtree фиксации, которая привела к ошибке. С подмодулями вы обнаружите, что фиксация, которая изменяет, submoduleвызывает ошибку, и вы вроде как SOL, если хотите быстро найти, какая фиксация в a submoduleвызывает ошибку в вашем основном проекте.
cyphar
1
Вот статья, в которой сравнивается git subtree и git submodule
8ctopus

Ответы:

58

Вам следует четко указать, о чем вы говорите, когда используете термин «поддерево» в контексте, gitпоскольку на самом деле здесь есть две отдельные, но связанные темы:

Стратегия слияния git-subtree и git subtree .

TL; DR

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

Подробнее

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

git-subtree - это сценарий оболочки-оболочки, обеспечивающий более естественный синтаксис. На самом деле это все еще часть contribи не полностью интегрировано в git с обычными страницами руководства. Документации вместо этого хранится вместе со стороны сценария.

Вот информация об использовании:

NAME
----
git-subtree - Merge subtrees together and split repository into subtrees


SYNOPSIS
--------
[verse]
'git subtree' add   -P <prefix> <commit>
'git subtree' add   -P <prefix> <repository> <ref>
'git subtree' pull  -P <prefix> <repository> <ref>
'git subtree' push  -P <prefix> <repository> <ref>
'git subtree' merge -P <prefix> <commit>
'git subtree' split -P <prefix> [OPTIONS] [<commit>]

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

Многое из того, что вы ищете , можно найти на этом блоге Atlassian по Nicola Паолуччи соответствующий раздел ниже:

Зачем использовать поддерево вместо подмодуля?

Есть несколько причин, по которым вам может быть subtreeлучше использовать:

  • Управлять простым рабочим процессом легко.
  • gitПоддерживаются более старые версии (даже более ранние v1.5.2).
  • Код подпроекта доступен сразу после cloneзавершения суперпроекта.
  • subtreeне требует от пользователей вашего репозитория изучать что-то новое, они могут игнорировать тот факт, что вы используете subtreeдля управления зависимостями.
  • subtreeне добавляет новые файлы метаданных, как submodulesделает (т.е. .gitmodule).
  • Содержимое модуля может быть изменено без наличия отдельной копии репозитория зависимости где-либо еще.

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

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

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

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

git-subtree в настоящее время не удается включить пульт!

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

Я также считаю этот пост в блоге очень информативным. Автор добавляет git-streeк смеси третий метод поддерева, который он вызывает . Статью стоит прочитать, так как он довольно хорошо сравнивает три подхода. Он высказывает свое личное мнение о том, что ему нравится, а что нет, и объясняет, почему он создал третий подход.

Дополнительно

Заключительные мысли

В этом разделе показаны как мощь, так gitи сегментация, которая может произойти, когда функция просто не попадает в цель.

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

Мэтью Сандерс
источник
12

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

В учебнике GitHub, на который вы указали, есть ссылка на Как использовать стратегию слияния поддеревьев, которая дает представление о преимуществах / недостатках:

Сравнение слияния поддеревьев с подмодулями

Преимущество использования слияния поддеревов состоит в том, что оно требует меньшей административной нагрузки со стороны пользователей вашего репозитория. Он работает со старыми (до Git v1.5.2) клиентами, и у вас есть код сразу после клонирования.

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

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

Вот моя точка зрения, основанная на вышеизложенном:

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

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

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

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

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

Лично я сам не решил, что использовать. Так что я разделяю ваше замешательство: o]

CFI
источник
3
Это самый категоричный ответ, который я видел, несмотря на противоречие, поскольку это единственный ответ и самоисполняющееся пророчество. Раздраженный вздох, суровое отношение к другим способностям к обучению - это очень высокомерный ответ. Ваше мнение о политике, вероятно, принадлежит Meta, где оно может быть полезно. Однако сам ответ, помимо корыстной болтовни, довольно хорош.
vgoff 05
1
@vgoff: Ваша критика верна. Извините за кажущееся высокомерие - это всего лишь более 15 лет опыта работы с людьми, которые за это время прошли обучение у разных людей в разных системах контроля версий и все еще копируют текстовые файлы во множество файлов .backup.<timestamp>. Думаю, с самого начала я ясно дал понять, что это будет самоуверенным. Остальные, надеюсь, смогут предоставить более фактическую информацию, и я удивлен, что еще никто этого не сделал.
cfi 05
Я все еще не понимаю. Вы говорите, что submoduleэто устаревший старый способ включения использованных библиотек и subtreeновый блестящий способ?
Lernkurve
Нет. Документы по крайней мере не упоминают, что какой-либо из этих двух устарел. И последнее слово остается за документами (кроме ошибок). Это просто два разных рабочих процесса, позволяющих выполнить одно и то же. У обоих есть достоинства и недостатки. Для меня тот факт, что никто из гуру git еще не ответил, является подтверждением того, что для эксперта различия незначительны. Скорее всего, используйте стратегию слияния поддеревьев, потому что она была реализована ранее и с которой люди знакомы read-tree(и в любом случае ветвление / слияние / удаленное управление). submodulesбыл добавлен
cfi
5

Реальный вариант использования, который у нас есть, когда git subtree было спасением:

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

Параллельно настраивается конкретная версия всего продукта для каждого из наших клиентов - отдельные филиалы для каждого модуля. Иногда настройку приходится производить сразу в нескольких проектах ( cross-module customization).

Чтобы иметь отдельный жизненный цикл продукта (обслуживание, ветки функций) для индивидуализированного продукта, мы ввели git subtree. У нас есть один репозиторий git-subtree для всех настраиваемых модулей. Наша настройка - это ежедневное возвращение всех исходных репозиториев к веткам настройки с помощью git subtree push.

Таким образом мы избегаем управления множеством репо и множеством филиалов. git-subtree повысил нашу производительность в несколько раз!

ОБНОВИТЬ

Подробнее о решении, опубликованном в комментариях:

Мы создали новый репозиторий. Затем мы добавили каждый проект, у которого была клиентская ветка, в это новое репо как поддерево. У нас была работа Дженкинса, которая регулярно откладывала основные изменения в исходные репозитории в клиентскую ветку. Мы работали только с «клиентским репо», используя типичный поток git с ветвями функций и обслуживания.

В нашем «клиентском» репозитории также были скрипты сборки, которые мы также адаптировали для этого конкретного клиента.

Однако в представленном решении есть подводный камень.

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

Марек Ягельски
источник
Марек, я столкнулся с похожей ситуацией, я относительно новичок в git и колеблюсь в возможностях. Я хотел бы узнать больше о вашей настройке.
goug 02
Я создал новый репозиторий. Затем я добавил каждый проект с клиентской веткой в ​​это репо как поддерево. У нас была работа Дженкинса, которая откладывала изменения в исходные репозитории в клиентскую ветку. В нашем клиентском репо мы нормально работали на главном сервере с функциональными ветками обслуживания.
Марек Ягельски
Ловушка заключалась в том, что мы уходили все дальше и дальше от основной разработки продукта. Так что возможное обновление для этого конкретного клиента становилось все труднее и труднее. В нашем случае это было нормально, так как состояние проекта перед поддеревом уже было далеко от основного пути, поэтому поддерево вводит как минимум порядок и возможность ввести поток git по умолчанию.
Марек Ягельски
Еще одна вещь: в нашем «клиентском» репозитории также были сценарии для сборки, которые мы также адаптировали для этого конкретного клиента.
Марек Ягельски
1
Я хотел бы порекомендовать вам включить в свой ответ дополнительную информацию из комментариев; они определенно дают лучший ответ.
Джеймс Скемп
5

В основном Git-subtree - это альтернатива подходу Git-submodule: есть много недостатков или, скорее, я бы сказал, вам нужно быть очень осторожным при использовании git-submodules. например, когда у вас есть «одно» репо, а внутри «одного» вы добавили другое репо с именем «два», используя подмодули. О чем нужно позаботиться:

  • Когда вы меняете что-то в «два», вам нужно зафиксировать и нажать внутрь «два», если вы находитесь в каталоге верхнего уровня (т.е. в «один»), ваши изменения не будут выделены.

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

Вот некоторые моменты, и для лучшего понимания я рекомендую вам посмотреть это видео: https://www.youtube.com/watch?v=UQvXst5I41I

  • Для решения таких проблем изобретен подход поддерева. Чтобы получить основные сведения о git-subtree, прочтите это: https://www.youtube.com/watch?v=t3Qhon7burE

  • Я считаю, что подход поддерева более надежен и практичен по сравнению с подмодулями :) (я очень новичок в таких вещах)

Ура!

SH '
источник
2

Чтобы добавить к приведенным выше ответам, дополнительным недостатком использования поддерева является размер репо по сравнению с подмодулями.

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

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

Однако, учитывая, что цены на хранение всегда снижаются, это не может быть существенным фактором.

Пол Филлипс
источник
Хранение - не проблема. Энтропия - это проблема ! Например, у вас есть 1000 инструментов размером от 10 до 100 КБ, каждый с общей кодовой базой размером, скажем, 35 ​​ГБ (поскольку он содержит огромное количество модулей из разных источников). С субмодулями вы передаете около 36 ГБ для всех, но, вероятно, более 1 ТБ с git subtree! Также обратите внимание, что субмодуль имеет явно несправедливое преимущество, если речь идет о git gcдедупликации ZFS (пакеты объектов). Следовательно, меньшие кодовые базы AFAICS (размер репо, а не количество репо) должны идти с подмодулями, большие - с монорепозиторием. Поддерево пока не нашел применения.
Тино
@tino Git отлично выводит поддеревья с общим кодом. Я просто провел несколько экспериментов, чтобы подтвердить. Для проверенного кода вам нужно будет запустить что-то вроде ZFS. Но субмодуль ничем не отличается.
Матиас