SVN: еквівалент зовнішніх даних у Git?


177

У мене є два SVN-проекти, які використовуються з іншого сховища SVN, використовуючи svn: externals .

Як я можу мати однакову структуру макета сховища в Git?


Ви повинні вивчити підмодулі Git . Це повинно дозволяти майже саме те, що ви шукаєте.
foxxtrot

7
Хтось має нову відповідь на це за останні 4 роки, чи світ git такий самий сьогодні?
DougW

4
@DougW Так, у мене є нова відповідь нижче : git submoduleтепер можна емулювати svn:external(з березня 2013 року).
VonC

Для останньої версії Git я пропоную прочитати про підмодулі Git в офіційній документації на Git.
Bulki S Maslom

Відповіді:


134

У Git є два підходи, схожі на svn: externals:

  • Злиття піддерева вставляють код зовнішнього проекту в окремий підкаталог у межах вашого репо. Це має детальний процес налаштування, а потім дуже просто для інших користувачів, оскільки він автоматично включається під час перевірки або клонування сховища. Це може бути зручним способом включити залежність у свій проект.
    Легко витягнути зміни з іншого проекту, але складно подати зміни назад. І якщо інший проект повинен злитися з вашим кодом, історія проекту об’єднується, і два проекти фактично стають одним.

  • Підмодулі Git ( посібник ) посилаються на певний комітет у сховищі іншого проекту, подібно до svn: externals з-rаргументом. Підмодулі легко налаштувати, але всі користувачі повинні керувати підмодулями, які не включаються автоматично в каси (або клони).
    Хоча повернення змін в інший проект легко, але це може спричинити проблеми, якщо репортаж змінився. Тому взагалі не годиться повертати зміни до проекту, який активно перебуває в стадії розробки.


17
FYI, тепер можна вказати конкретні зміни з svn: externals зараз (оскільки я вважаю, 1,5 чи 1,6?)
Нейт Парсонс

9
FYI, підмодулі git можуть бути автоматично керовані та зафіксовані. git створює .gitmodules файл, який можна / слід заповнити так само, як файл .gitignore. Для отримання додаткової інформації див. [ Git-scm.com/book/en/Git-Tools-Submodules] .
mikijov

5
@NateParsons Завжди можна було вказати точні номери версій за допомогою svn:externals. З версією 1.5 синтаксис було змінено на більш гнучкий формат. Додано відносну URL-адресу.
David W.

@NateParsons, але чи можна опустити зміни з підмодулями git ...> _>
Trejkaz

Я думаю, що неможливо зібрати підмодуль одного файлу, як із svn: externals
user1911091

38

Як я вже згадував у " Оновлення нової версії підмодуля Git ", ви можете досягти тієї ж зовнішньої функції SVN з підмодулями Git 1.8.2:

git config -f .gitmodules submodule.<path>.branch <branch>

Цього цілком достатньо, щоб підмодуль слідував за гілкою (як у ПОСЛІДНІЙ комісії віддаленої гілки підмодуля верхнього репо-репо ). Все, що вам потрібно зробити, це:

git submodule update --remote

Це оновить підмодуль.

Більш детальна інформація знаходиться у " git submoduleвідстеженні останніх "

Щоб перетворити існуючий підмодуль в одну відстежуючу гілку : перегляньте всі кроки в " Підмодулі Git: Вкажіть гілку / тег ".


Чи можете ви зробити часткову касу, як у svn:externals?
nowox

@nowox Так, ви можете мати рідкісну перевірку (мерзотник 1.7+ stackoverflow.com/a/2372044/6309 ) , пов'язані подмодулей ( stackoverflow.com/a/17693008/6309 )
VonC

на жаль, всі відповіді на рідкісні замовлення ніколи не дають жодного прикладу :( Я спробую написати приклад для цього ...
nowox

З цим все ще існує проблема. Вам все одно доведеться отримати всю історію сховища, де вам потрібна лише одна невелика частина. У моєму випадку 100 кБ понад 2 Гб. Я, звичайно, можу використовувати, --depthале це не дуже вирішує проблему.
nowox

@nowox Найкраще задати нове запитання, пояснюючи, що саме стосується вашого використання: я не маю поняття, чи є ваш репо 2 Гб підмодулем чи основним репо з підмодулем, і що саме вам потрібно витягти з нього.
VonC

3

Я автор інструменту gil (git link)

У мене є альтернативне рішення проблеми - інструмент gil (git links)

Це дозволяє описувати та керувати складними залежностями git-сховищ.

Крім того, він забезпечує вирішення проблеми залежності рекурсивних субмодулів git .

Розглянемо, що у вас є такі проектні залежності: зразок графіка залежності репозиторію git

Тоді ви можете визначити .gitlinksфайл із описом відношення репозиторіїв:

# Projects
CppBenchmark CppBenchmark https://github.com/chronoxor/CppBenchmark.git master
CppCommon CppCommon https://github.com/chronoxor/CppCommon.git master
CppLogging CppLogging https://github.com/chronoxor/CppLogging.git master

# Modules
Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git master
cpp-optparse modules/cpp-optparse https://github.com/weisslj/cpp-optparse.git master
fmt modules/fmt https://github.com/fmtlib/fmt.git master
HdrHistogram modules/HdrHistogram https://github.com/HdrHistogram/HdrHistogram_c.git master
zlib modules/zlib https://github.com/madler/zlib.git master

# Scripts
build scripts/build https://github.com/chronoxor/CppBuildScripts.git master
cmake scripts/cmake https://github.com/chronoxor/CppCMakeScripts.git master

Кожен рядок описує посилання git у такому форматі:

  1. Унікальна назва сховища
  2. Відносний шлях сховища (починається з шляху файлу .gitlinks)
  3. Репозиторій Git, який буде використовуватися в команді git clone відділення репозиторію для оформлення замовлення
  4. Порожній рядок або рядок, розпочатий з #, не розбираються (трактуються як коментар).

Нарешті, вам потрібно оновити сховище кореневого зразка:

# Clone and link all git links dependencies from .gitlinks file
gil clone
gil link

# The same result with a single command
gil update

В результаті ви будете клонувати всі необхідні проекти та зв’язувати їх один з одним належним чином.

Якщо ви хочете здійснити всі зміни в деякому сховищі зі всіма змінами в сховищах, пов’язаних з дочірніми, ви можете зробити це за допомогою однієї команди:

gil commit -a -m "Some big update"

Команди "pull", "push" працює аналогічно:

gil pull
gil push

Інструмент Gil (git-посилання) підтримує такі команди:

usage: gil command arguments
Supported commands:
    help - show this help
    context - command will show the current git link context of the current directory
    clone - clone all repositories that are missed in the current context
    link - link all repositories that are missed in the current context
    update - clone and link in a single operation
    pull - pull all repositories in the current directory
    push - push all repositories in the current directory
    commit - commit all repositories in the current directory

Детальніше про проблему залежності рекурсивних субмодулів git .


1
У верхній частині публікації слід поставити відмову, сказавши, що ви є автором gil.
Даніель Каміль Козар
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.