Укажите ветку для подмодуля git? - PullRequest
0 голосов
/ 02 марта 2019

Я добавил подмодуль git в свой репозиторий git, и он отлично работает.

В моем «родительском» репозитории я создал ветку объектов: myfeature , которая требует некоторых изменений всубмодуль.Но я не хочу влиять на другие команды, используя тот же субмодуль.Поэтому я создал соответствующую ветку объектов в хранилище подмодулей submodule-feature с некоторыми изменениями.Затем я добавил / committet изменение из каталога подмодулей, а затем то же самое в корне родительского репозитория.

Но когда я переключаюсь на master в моем «родительском» репозитории,субмодуль по-прежнему находится в ветви submodule-feature .Это не то, что я ожидаю.Потому что теперь, когда я запускаю свои тесты на master , они терпят неудачу, потому что я ввел некоторые критические изменения в подмодуле в ветке submodule-feature .

Разве это невозможно? заблокировать ветвь подмодуля для родительской ветви репозитория?

РЕДАКТИРОВАТЬ: На основе: Как указать ветку / тег при добавлении подмодуля Git?

Похоже, я могу указать ветку для хранилища подмодуля в .gitmodules

[submodule "mysubmodule"]
    path = mysubmodule
    url = https://bla.git
    branch = submodule-feature

И добавить следующее дополнительное поведение git в jenkins:

enter image description here

и:

enter image description here

клонирует / извлекает ветку submodule-feature при запуске сборки на parent myfeature branch.

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

1 Ответ

0 голосов
/ 03 марта 2019

Короткий ответ: просто в основном "нет".Хотя у Дженкинса есть флажок, его использование здесь может быть не очень хорошим, зависит от того, кто его контролирует, сопоставление имени и идентификатора.Другие системы CI могут иметь или не иметь аналогичные флажки.Чтобы увидеть, к чему я клоню, читайте дальше.

Философия подмодулей заключается в том, что суперпроект контролирует свои подмодули.Эта часть, я думаю, ни для кого не является ни удивительной, ни нежелательной.Но ключ кроется в способе , которым суперпроект управляет каждым подмодулем.Эта часть удивляет людей , и причина довольно проста.Это основное неправильное понимание Git-репозиториев в целом.

Люди думают, что в Git-репозиториях важны ветви , или, точнее, ветви names наподобие master иdevelop.Это просто неправда.Эти ветви, по большей части, практически не имеют значения здесь.Для людей эти названия ветвей служат огромной, первостепенной цели.Для Git они служат в основном тривиальной точкой, которая одинаково хорошо покрыта любым другим именем, таким как имя тега или имя удаленного отслеживания, или refs/stash, или HEAD@{17}. 1

В Git * * * * * commit , а не имя ветви (ни имя тега, ни какое-либо другое имя), является центральной, важной вещью.Комитеты - это Git's raison d'être .Без коммитов Git не работает.С коммитами Git полезен.Коммиты фактически идентифицируются по их хэш-идентификаторам, настоящими именами которых являются те большие уродливые строки, как b5101f929789889c2e536d915698f58d5c5c6b7a.Глупые вещи, такие как читаемые имена, такие как master или develop, предназначены для слабых, биологических ... людей.

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

Так что в этом и заключается сюрприз, за ​​исключением того, что когда вы понимаете, откуда идет Git, это совсем не удивительно. Когда вы разрешаете суперпроекту выбирать фиксацию подмодуля, суперпроект выбирает фиксацию субмодуля по хеш-идентификатору.Любые имена ветвей не имеют значения. Идентификатор хеша точен и всегда корректен.Имена ветвей неаккуратны - они нарочно перемещаются из коммита в коммит со временем.Один идентификатор хэша коммита может иметь ноль или более имен ветвей, которые либо указывают прямо на него, либо могут достигать его через граф фиксации. 2

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

Помните, что каждый подмодуль является собственным Git-репозиторием, поэтому у него есть свой HEAD, индекс и рабочее дерево.Индекс в подмодуле записывает файлы, извлеченные в рабочее дерево подмодуля, а HEAD в каждом подмодуле находится в режиме detached HEAD , записывая хэш-идентификатор проверенного в данный момент идентификаторасовершитьЭто Git суперпроекта, который выбирает этот хэш-идентификатор - сохраняя его в коммите в суперпроекте - и ответственность подмодуля Git состоит в том, чтобы проверить этот конкретный коммит.Нигде в этом процессе нет никакого упоминания названия ветви.Названия ветвей не имеют значения!


1 Функция имен в Git, помимо, конечно, обеспечения опоры для слабых людей, заключается в защите объектов от сбора мусора .Объект уязвим для сбора, если он недоступен от какого-либо имени.Поскольку большинство коммитов в основном связаны друг с другом, одно имя защищает большинство коммитов в хранилище.См. Также сноску 2.

2 Подробнее о достижимости см. Think Like (a) Git .

3 Это на самом деле не происходит автоматически по умолчанию.Вы должны использовать git checkout --recurse-submodules или установить submodule.recurse в вашей конфигурации.В зависимости от того, что вы делаете, особенно если вы пытаетесь обновить подмодули, автоматическое выполнение этого может быть либо удобным, либо крайне раздражающим.


Почему тогда вы можете установить веткуимя в первую очередь?

Как вы заметили, в файл .gitmodules можно записать имя ветви.Вы также можете скопировать это в .git/config (настройка .git/config переопределяет настройку .gitmodules, если установлены оба.) Но, как правило, подмодуль вообще не находится в ветви;он переводится в режим HEAD, как описано выше.Так что же хорошего в том, что это название ветви?

Первый, но несколько неудовлетворительный ответ: Это совсем не хорошо. Большинство операций просто не используют его.

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

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

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

git submodule update --remote

(к которому вы можете добавить некоторые дополнительные флаги, такие как --checkout или --rebase или --merge, но я не собираюсьчтобы разобраться в этих деталях - сейчас я предполагаю, что вы просто используете их последние версии напрямую).В вашем Git ваш подмодуль Git запускается git fetch, а затем обновляет ваш репозиторий подмодулей до своего последнего коммита, как указано в копии вашего подмодуля с именем их ветви.(Сейчас во всем этом задействовано по крайней мере трех Gits - ваш суперпроект, ваш подмодуль и Git-репозиторий на GitHub - так что это немного сложно. У них, кем бы они ни были, вероятно, есть один или несколько Gitрепозитории, которые они используют для управления GitHub, но, по крайней мере, вам не нужно иметь с этим дело. Ну, пока нет.)

ТеперьКогда ваш подмодуль обновляется, вы должны исправить свой собственный код, чтобы использовать новую функцию и справляться со всеми существенными изменениями, которые они внесли в то, что вы уже использовали.Таким образом, вы делаете все это, собирая и тестируя свое программное обеспечение - все на своем локальном компьютере: здесь нет никакой CI, и пока - все это работает. Теперь вы можете git add внести изменения и git add имя субмодуля.Индекс и рабочее дерево вашего суперпроекта теперь совпадают, и вы готовы сделать новый коммит в вашем суперпроекте.

Обратите внимание, что git add <em>submodule-path</em> просто велел вашему Git записать в ваш индекс хэш-идентификатор коммита, который в настоящее время извлечен в вашем подмодуле Git-репозитория.Еще раз, имя ветки, если оно есть, не имеет значения. Не имеет значения, находится ли ваш репозиторий субмодулей в ветке master или develop или имеет отсоединенную головку;все, что имеет значение, это необработанный хэш-идентификатор .

Теперь вы запускаете git commit, чтобы сделать новый коммит.Идентификатор хеша из вашего индекса, который контролирует, какой коммит будет считаться «правильным» коммитом для подмодуля, - это хеш-код коммита, который вы записали, запустив git add <em>submodule-path</em>. В этом случае , этот идентификатор фиксации получил , выбранный из-за того, что вы запустили git submodule update --remote ранее.Но единственное, что имеет значение, - это хеш-идентификатор в вашем индексе, который входит в новый коммит.

Теперь вы можете git push этот коммит, который вы сделали в своем суперпроекте Gitхранилище, в какую-то другую систему, такую ​​как ваша система CI.Он может git checkout сделать этот коммит, и этот коммит записывает правильный хеш-идентификатор подмодуля.

Как я могу объединить это с системой CI, чтобы система CI выбирала хэш-идентификатор?

Это , очевидно, намного сложнее может быть сложнее, в зависимости от того, предлагает ли ваша система CI это как функцию.

Теперь, когда вы знаете, как все это построеноТем не менее, у вас есть инструменты, которые вам нужны.Ваша система CI должна обновить (или получить) свой клон суперпроекта.Этот суперпроект содержит в своем файле .gitmodules URL-адрес и путь для любых подмодулей, которые система CI должна также клонировать.Он может содержать или не содержать некоторые имена ветвей для этих подмодулей.

Система CI должна теперь направить некоторый Git - суперпроект Git или подмодуль Git - на подмодуль Git git checkout некоторый коммит отличный от тот, который уже записан как правильный коммит, так что суперпроект больше не использует коммит, полученный системой CI.Другими словами, вы больше не создаете то, что отправили в систему CI .У вас есть система CI, которая строит нового монстра Франкенштейна из частей тела: основной части вашего коммита, но конечности, взятой из какого-то другого коммита, который вы не указали напрямую: вместо этого вы 'позволяя кому-то еще указать, какой коммит идет туда.Вы дали своей системе CI имя и сказали ей спросить их, кем бы они ни были, какой хеш-идентификатор у этого имени.

Ваша система CI теперь может пытаться создать и использовать этот Франкенштейн.-monster.Если все работает хорошо, ваша система CI должна будет сделать новый коммит, это очень похоже на ваш коммит, за исключением того, что он записывает хэш-идентификатор , который он получилот их - кем бы они ни были, опять же - для рассматриваемого подмодуля.Ваша система CI, вероятно, теперь также нуждается в разрешении для проталкивания этого коммита куда-либо, если только ваша система CI не является вашим основным источником правды для репозитория.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...