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

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

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

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

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


person Lernkurve    schedule 04.09.2015    source источник
comment
разделение репозитория! = несвязанные репозитории думают о зависимостях в вашем репо, и вы не хотите использовать подмодули (по какой-то причине, возможно, вам не нравится, что они непрозрачны и что пути в коммитах в подмодуле не соответствовать вашему пути в основном репозитории git).   -  person cyphar    schedule 06.09.2015
comment
@cyphar: Вы говорите, что и submodule, и subtree более или менее достигают одной и той же цели, которая включает связанные проекты, и что единственная разница в том, что submodule может быть немного менее прозрачным, а обновление подмодулей - это двухэтапная операция, и что недостаток из subtree в том, что сообщения о фиксации будут смешиваться между двумя проектами?   -  person Lernkurve    schedule 06.09.2015
comment
Что ж, в некоторых случаях это не является недостатком. Например, если вам нужно разделить пополам репозиторий, в котором есть subtrees, и в зависимости была введена ошибка, вы найдете точную фиксацию в subtree, которая привела к ошибке. С подмодулями вы обнаружите только, что фиксация, которая изменяет submodule, вызывает ошибку, и вы вроде как SOL, если хотите быстро найти, какая фиксация в submodule вызывает ошибку в вашем основном проекте.   -  person cyphar    schedule 07.09.2015
comment
Вот статья, в которой сравнивается git subtree и git submodule с практическими примерами nering.dev/2016/ git-submodules-vs-subtrees   -  person 8ctopus    schedule 28.06.2020


Ответы (5)


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

git-subtree и стратегия слияния поддеревьев git.

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 blog Никола Паолуччи в соответствующем разделе ниже:

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

Есть несколько причин, по которым вам может показаться, что 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, однако, в настоящее время гораздо более известен, поэтому, очевидно, хорошо знать об этом и зависит от вашей аудитории, которая может повлиять на ваше решение.

person Matthew Sanders    schedule 07.11.2015

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ваше здоровье!

person SH'    schedule 07.05.2017

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

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

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

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

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

ОБНОВЛЕНИЕ

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

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

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

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

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

person Marek Jagielski    schedule 18.11.2015
comment
Марек, я столкнулся с похожей ситуацией, и я относительно новичок в git и колеблюсь в возможностях. Я хотел бы узнать больше о вашей настройке. - person goug; 02.08.2018
comment
Я создал новый репозиторий. Затем я добавил каждый проект, у которого была клиентская ветка, в это репо как поддерево. У нас была работа Дженкинса, которая откладывала изменения в исходные репозитории в клиентскую ветку. На нашем клиентском репо мы нормально работали на главном сервере с функциональными ветками обслуживания. - person Marek Jagielski; 02.08.2018
comment
Ловушка заключалась в том, что мы уходили все дальше и дальше от основной разработки продукта. Таким образом, возможное обновление для этого конкретного клиента становилось все труднее и труднее. В нашем случае это было нормально, поскольку состояние проекта перед поддеревом уже было далеко от основного пути, поэтому поддерево вводит как минимум порядок и возможность ввести поток git по умолчанию. - person Marek Jagielski; 02.08.2018
comment
Еще одна вещь: в нашем «клиентском» репозитории также были скрипты для сборки, которые мы также адаптировали для этого конкретного клиента. - person Marek Jagielski; 02.08.2018
comment
Отличный пример! Хотел бы я дать вам больше голосов. - person Jan Warchoł; 13.02.2019
comment
Я хотел бы порекомендовать вам включить в свой ответ дополнительную информацию из комментариев; они определенно дают лучший ответ. - person James Skemp; 19.07.2019

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

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

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

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

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