Коли використовувати піддерево git?


81

Яку проблему git subtreeвирішує? Коли і навіщо мені використовувати цю функцію?

Я читав, що він використовується для розділення сховища . Але чому б мені не просто створити два незалежних сховища, замість того, щоб склеїти два не пов’язаних між собою сховища в одне?

Цей підручник GitHub пояснює, як виконувати злиття піддерев Git .

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


1
"repository separation"! = "не пов'язані сховища" думають про залежності у вашому репозиторії, і ви не хочете використовувати підмодулі (з якихось причин, можливо, вам не подобається, що вони не прозорі і що шляхи в комітах у підмодуль не відповідає вашому шляху в головному репозиторії git).
cyphar

1
@cyphar: Ви хочете сказати, що і ті, submoduleі subtreeінші більш-менш досягають тієї самої мети, яка включає пов'язані проекти, і що єдина відмінність полягає в тому, що submoduleможе бути трохи менш прозорою, і оновлення підмодулів є двоступеневою операцією і що недоліком subtreeє повідомлення про комітети будуть змішані між двома проектами?
Lernkurve

1
Ну, це насправді не є недоліком у певних випадках. Наприклад, якщо вам потрібно розділити сховище, яке має subtrees, і помилка була введена в залежність, точний коміт ви знайдете в тому,subtree який ввів помилку. За допомогою підмодулів ви виявите, що коміт, який змінив submoduleпричину , викликав помилку, і ви начебто SOL, якщо хочете швидко знайти, який коміт у причині submoduleвикликає помилку у вашому основному проекті.
cyphar

1
Ось стаття, яка порівнює піддерево git і підмодуль git з практичними прикладами nering.dev/2016/git-submodules-vs-subtrees
8ctopus

Відповіді:


58

Ви повинні бути обережними, щоб чітко зазначити, про що йдеться, коли ви використовуєте термін „піддерево” у контексті, gitоскільки насправді тут є дві окремі, але пов’язані теми:

стратегія злиття git-subtree та git subtree .

TL; DR

Обидві концепції, пов'язані з піддеревом, ефективно дозволяють управляти кількома сховищами в одному. На відміну від git-підмодуля, де у кореневому сховищі зберігаються лише метадані, у формі .gitmodules , і ви повинні керувати зовнішніми сховищами окремо.

Детальніше

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

git-subtree - це сценарій оболонки-обгортки для полегшення більш природного синтаксису. Це насправді все ще частина contribі не повністю інтегрована в git зі звичайними сторінками man. документація зберігається поряд із сценарієм.

Ось інформація про використання:

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 від Ніколи Паолуччі у відповідному розділі нижче:

Навіщо використовувати піддерево замість підмодуля?

Є кілька причин, чому вам може бути 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]


3
Ця відповідь є найзахитнішою, яку я бачив, незважаючи на суперечливість, оскільки це єдина відповідь, і самореалізоване пророцтво. Роздратований зітхання, ставлення думника до здатності інших вчитися - це дуже зарозуміла відповідь. Ваша думка щодо політики, ймовірно, належить компанії Meta, де вона може бути корисною. Сама відповідь, окрім самообслуговування пуху, досить хороша.
vgoff

1
@vgoff: Ваша критика правильна. Вибачте, що, здавалося б, зарозумілий - це лише> 15 років досвіду роботи з людьми, яких за той час навчали різні люди в різних системах контролю версій і досі копіювали текстові файли в безліч .backup.<timestamp>. Думаю, я вже на початку дав зрозуміти, що це буде сумнів. Інші, сподіваємось, зможуть надати більш реальну інформацію, і я дивуюсь, що цього ще ніхто не зробив.
cfi

Я все ще не розумію. Ви хочете сказати, що submoduleце застарілий застарілий спосіб включення використаних бібліотек, а subtreeце новий блискучий спосіб?
Лернкурве,

Ні. У документах, принаймні, не згадується, що будь-який із них є застарілим. І для мене останнє слово мають документи (крім помилок). Це лише два різні робочі процеси, щоб виконати подібне. І те, і інше має переваги та недоліки. Для мене той факт, що ще ніхто з гуру git не відповів, є підтвердженням того, що для експерта відмінності незначні. Швидше за все, використовується стратегія злиття піддерев, оскільки це та, яка була впроваджена раніше, і люди знайомі read-tree(і в будь-якому випадку розгалуження / злиття / віддалене управління). submodulesбув доданий
cfi

5

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

Основним продуктом нашої компанії є висока модульність і розробка в декількох проектах в окремих сховищах. Усі модулі мають свою окрему дорожню карту. Весь продукт складається з усіх модулів конкретних варіантів.

Паралельно конкретна версія цілого продукту налаштована для кожного з наших клієнтів - окремі відділення для кожного модуля. Індивідуалізацію доводиться робити іноді в декількох проектах одночасно ( cross-module customization).

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

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

ОНОВЛЕННЯ

Детальніше про рішення, яке було розміщено в коментарях:

Ми створили нове сховище. Потім ми додали кожен проект, який мав гілку клієнта, до цього нового репо як піддерево. У нас була робота jenkins, яка регулярно відтісняла основні зміни до оригінальних сховищ до гілки клієнта. Ми працювали просто з "клієнтським репо", використовуючи типовий git-потік із функціями та гілками обслуговування.

У нашому репозиторії "клієнта" були також побудовані сценарії, які ми також адаптували для цього конкретного клієнта.

Однак є підводне рішення представленого рішення.

Оскільки ми йшли все далі і далі від основної основної розробки продукту, можливе оновлення для цього конкретного клієнта було дедалі складнішим. У нашому випадку це було нормально, оскільки стан проекту до того, як піддерево було вже далеко основним шляхом, тому піддерево вводить принаймні порядок і можливість запровадити git-потік за замовчуванням.


Марек, я стикаюся з такою ж ситуацією, і я відносно новачок у шахрайстві та базіканні можливостей. Я хотів би дізнатися більше про вашу установку.
goug

Я створив абсолютно нове сховище. Потім я додав кожен проект, який мав гілку клієнта, до цього репо як піддерево. У нас була робота jenkins, яка відштовхувала зміни до оригінальних сховищ до гілки клієнта. На нашому клієнтському репо ми нормально працювали над майстром з філіями, гілками обслуговування.
Марек Ягельський

Підводним каменем було те, що ми йшли все далі і далі від основної основної розробки продукту. Тож можливе оновлення для цього конкретного клієнта було дедалі складнішим. У нашому випадку це було нормально, оскільки стан проекту до того, як піддерево було вже далеко основним шляхом, тому піддерево вводить принаймні порядок і можливість запровадити git-потік за замовчуванням.
Марек Ягельський

Ще одна річ, що у нашому репозиторії "клієнта" також були сценарії побудови, які ми також адаптували для цього конкретного клієнта.
Марек Ягельський

1
Я хотів би рекомендувати вам включити вашу додаткову інформацію з коментарів у вашу відповідь; вони, безумовно, роблять це кращою відповіддю.
Джеймс Скемп,

5

В основному Git-subtree є альтернативами підходу Git-submodule: Є багато недоліків, або, скоріше, я б сказав, потрібно бути дуже обережним під час використання git-підмодулів. наприклад, коли у вас є "одне" репо та всередині "одне", ви додали ще одне репо, яке називається "два", використовуючи підмодулі. Що потрібно подбати:

  • Коли ви змінюєте щось у "два", вам потрібно зафіксувати та ввести всередину "два", якщо ви знаходитесь у каталозі верхнього рівня (тобто в "одному"), ваші зміни не будуть виділятися.

  • Коли невідомий користувач намагається клонувати ваше репозиторій "один", після клонування "одного" користувачеві потрібно оновити підмодулі, щоб отримати репозиторій "два"

Ось деякі моменти, і для кращого розуміння я рекомендую вам переглянути це відео: https://www.youtube.com/watch?v=UQvXst5I41I

  • Для подолання таких проблем винайдено піддерево. Щоб отримати основи роботи з git-subtree, ознайомтеся з цим: https://www.youtube.com/watch?v=t3Qhon7burE

  • Я вважаю, що піддерево є більш надійним і практичним порівняно з підмодулями :) (я дуже початківець, щоб говорити про ці речі)

Ура!


2

Щоб додати до вищезазначених відповідей, додатковим недоліком використання піддерева є розмір репо в порівнянні з підмодулями.

У мене немає реальних показників, але з огляду на те, що кожного разу, коли здійснюється натискання на модуль, скрізь цей модуль отримує копію тієї ж зміни на батьківському модулі (коли згодом оновлюється на цих репозиторіях).

Отже, якщо база коду сильно модулізована, це складеться досить швидко.

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


Зберігання не є проблемою. Проблема в ентропії ! Наприклад, у вас є 1000 інструментів розміром від 10 КБ до 100 КБ, кожна із яких використовує загальну кодову базу, скажімо, 35 ГБ (оскільки вона містить величезну кількість модулів з різних джерел). З підмодулями ви передаєте близько 36 ГБ на всіх, але, мабуть, більше 1 ТБ з піддеревом git! Також зверніть увагу, що підмодуль має явно несправедливу перевагу, якщо мова йде про git gcдедупцію ZFS (об'єктні пакети). Отже, AFAICS менші бази кодів (розмір репо, а не підрахунок репо) повинні йти з підмодулями, більші - з монорепо. Я ще не знайшов застосування для піддерева.
Тіно

@tino Git дуже добре виводить піддерева із загальним кодом. Я просто провів кілька експериментів для підтвердження. Для зареєстрованого коду вам потрібно буде запустити щось на зразок ZFS. Але підмодуль не відрізняється.
Matthias
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.