Как сделать мелкие подмодули git?

139

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

Все, что я нашел, является этой оставшейся без ответа веткой .

Должен ли я просто взломать git-submodule для реализации этого?

Маурисио Шеффер
источник
1
" git submodule add/update" теперь можно поверхностно клонировать репозитории субмодулей! Смотрите мой ответ ниже
VonC

Ответы:

133

Новое в готовящемся выпуске git1.8.4 (июль 2013 г.) :

" git submodule update" может необязательно клонировать репозитории субмодулей.

(И git 2.10 Q3 2016 позволяет записать это с помощью git config -f .gitmodules submodule.<name>.shallow true.
См. Конец этого ответа)

Смотрите коммит 275cd184d52b5b81cb89e4ec33e540fb2ae61c1f :

Добавьте --depthопцию к командам добавления и обновления «git submodule», которая затем передается команде clone. Это полезно, когда субмодуль (ы) огромен, и вы на самом деле не заинтересованы ни в чем, кроме последнего коммита.

Добавлены тесты и внесены некоторые коррективы в отступы, чтобы они соответствовали остальной части тестового файла: «Обновление подмодуля может обрабатывать символические ссылки в pwd».

Подписано: Фредрик Густафссон <iveqy@iveqy.com>
Автор: Йенс Леманн<Jens.Lehmann@web.de>

Это означает, что это работает:

git submodule add --depth 1 -- repository path
git submodule update --depth -- [<path>...]

С участием:

--depth::

Эта опция действительна для addи updateкоманды.
Создайте «мелкий» клон с историей, усеченной до указанного количества ревизий.


atwyman добавляет в комментариях :

Насколько я могу судить, эта опция не может использоваться для субмодулей, которые не masterочень внимательно отслеживают . Если вы установите глубину 1, то submodule updateуспех может произойти только в том случае, если требуемый коммит подмодуля является последним мастером. В противном случае вы получите " fatal: reference is not a tree" .

Это правда.
То есть до git 2.8 (март 2016). С 2.8 у submodule update --depthнего есть еще один шанс на успех, даже если SHA1 напрямую доступен с одного из удаленных репозиториев HEAD.

См. Коммит fb43e31 (24 февраля 2016 г.) Стефана Беллера ( stefanbeller) .
Помогает: Junio ​​C Hamano ( gitster) .
(Слиты Junio C Hamano - gitster- в фиксации 9671a76 , 26 Feb 2016)

субмодуль: стараться изо всех сил выбрать нужный sha1 путем прямого выбора sha1

При проверке изменения, которое также обновляет подмодуль в Gerrit, обычной практикой проверки является загрузка и выборочная установка патча локально для его тестирования.
Однако при локальном тестировании ' git submodule update' может не удастся выбрать правильный подмодуль sha1, поскольку соответствующий коммит в подмодуле еще не является частью истории проекта, но также является предложенным изменением.

Если $sha1не было частью выборки по умолчанию, мы пытаемся получить $sha1напрямую . Однако некоторые серверы не поддерживают прямую выборку с помощью sha1, что приводит git-fetchк быстрому сбою.
Мы можем здесь потерпеть неудачу, так как все еще отсутствующий sha1 в любом случае приведет к неудаче на этапе оформления заказа, поэтому неудача здесь настолько хороша, насколько мы можем это сделать.


В комментариях MVG указывает на коммит fb43e31 (git 2.9, февраль 2016 г.)

Казалось бы , что мне совершить fb43e31 запросы недостающее совершать по SHA1 идентификатор, так uploadpack.allowReachableSHA1InWantи uploadpack.allowTipSHA1InWantнастройки на сервере, вероятно , повлияет ли это работает. Сегодня
я написал сообщение в список git , в котором указывалось, как использовать мелкие подмодули, чтобы они работали лучше для некоторых сценариев, а именно, если commit также является тегом.
Давайте подождем и посмотрим.

Я предполагаю, что это причина, почему fb43e31 сделал выборку для конкретного SHA1 резервным после выборки для ветви по умолчанию.
Тем не менее, в случае «--depth 1» я думаю, что было бы целесообразно прервать работу раньше: если ни один из перечисленных ссылок не соответствует запрошенному, и запрос от SHA1 не поддерживается сервером, то нет смысла получить что-нибудь, так как мы не сможем удовлетворить требование субмодуля в любом случае.


Обновление август 2016 (3 года спустя)

С Git 2.10 (3 квартал 2016 года) вы сможете делать

 git config -f .gitmodules submodule.<name>.shallow true

Смотрите " Git submodule без лишнего веса " для более подробной информации.


Git 2.13 (второй квартал 2017 года) добавлен в коммит 8d3047c (19 апреля 2017 года) Себастьяном Шубертом ( sschuberth) .
(Объединено Себастьяном Шубертом - sschuberth- в коммите 8d3047c , 20 апреля 2017 г.)

клон этого подмодуля будет выполнен как мелкий клон (с глубиной истории 1)

Тем не менее, Сиро Сантилли добавляет в комментариях (и подробности в своем ответе )

shallow = trueна .gitmodulesвлияет только ссылка отслеживаются ГОЛОВЕ пульта дистанционного при использовании --recurse-submodules, даже если цель коммита указывает ветвь, и даже если вы поставите branch = mybranchна.gitmodules а.


В Git 2.20 (Q4 2018) улучшена поддержка субмодулей, которая была обновлена ​​для чтения из большого двоичного объекта по адресу HEAD:.gitmodules когда .gitmodulesфайл отсутствует в рабочем дереве.

См. Коммит 2b1257e , коммит 76e9bdc (25 октября 2018 г.) и коммит b5c259f , коммит 23dd8f5 , коммит b2faad4 , коммит 2502ffc , коммит 996df4d , коммит d1b13df , коммит 45f5ef3 , коммит bcbc780 (05 окт 2018) Антонио Оспите ( ao2) .
(Слиты Junio C Hamano - gitster- в фиксации abb4824 , 13 ноября 2018)

submodule: поддержка чтения .gitmodules когда его нет в рабочем дереве

Если .gitmodulesфайл недоступен в рабочем дереве, попробуйте использовать содержимое из индекса и из текущей ветви.
Это относится к случаю, когда файл является частью хранилища, но по какой-то причине он не извлечен, например, из-за разреженной проверки.

Это позволяет использовать как минимум git submoduleкоманды, которые читают в gitmodulesконфигурационный файл без полного заполнения рабочего дерева.

Запись в .gitmodules все равно потребуется извлечение файла, поэтому проверьте его перед вызовом config_set_in_gitmodules_file_gently.

Добавьте аналогичную проверку также, git-submodule.sh::cmd_add()чтобы предвидеть возможный сбой команды " git submodule add", когда .gitmodulesзапись не может быть безопасно выполнена; это препятствует тому, чтобы команда оставила хранилище в ложном состоянии (например, хранилище подмодуля было клонировано, но .gitmodulesне было обновлено из-за config_set_in_gitmodules_file_gentlyсбоя).

Более того, поскольку config_from_gitmodules()теперь осуществляется доступ к глобальному хранилищу объектов, необходимо защитить все пути кода, которые вызывают функцию, от одновременного доступа к глобальному хранилищу объектов.
В настоящее время это происходит только в builtin/grep.c::grep_submodules(), так что вызывайте grep_read_lock()перед вызовом кода с участием config_from_gitmodules().

ПРИМЕЧАНИЕ: есть один редкий случай, когда эта новая функция еще не работает должным образом: вложенные подмодули без .gitmodulesрабочего дерева.


Примечание: Git 2.24 (Q4 2019) исправляет возможную ошибку сегмента при клонировании мелкого субмодуля.

См. Коммит ddb3c85 (30 сентября 2019 г.) Али Утку Селен ( auselen) .
(Слиты Junio C Hamano - gitster- в фиксации 678a9ca , 09 окт 2019)


Git 2.25 (Q1 2020), уточняет git submodule update документацию.

См. Сообщение f0e58b3 (24 ноября 2019 г.) от Philippe Blain ( phil-blain) .
(Слиты Junio C Hamano - gitster- в фиксации ef61045 , 05 дек 2019)

doc: упомяните, что 'git submodule update' выбирает отсутствующие коммиты

Помощник: Джунио С. Хамано.
Помощник: Йоханнес Шинделин
Подпись: Филипп Блен

« git submoduleupdate» будет получать новые коммиты с пульта субмодуля, если SHA-1, записанный в суперпроекте, не найден . Это не было упомянуто в документации.


Предупреждение: В Git 2.25 (Q1 2020) взаимодействие между " git clone --recurse-submodules" и хранилищем альтернативных объектов было плохо спроектировано.

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

Смотрите коммит 4f3e57e , коммит 10c64a0 (02 декабря 2019 г.) Джонатана Тана ( jhowtan) .
(Слиты Junio C Hamano - gitster- в фиксации 5dd1d59 , 10 дек 2019)

submodule--helper: посоветуйте фатальную альтернативную ошибку

Подписано: Джонатан Тан
Автор: Джефф Кинг

При рекурсивном клонировании суперпроекта с некоторыми мелкими модулями, определенными в его .gitmodules, и последующем клонировании с " --reference=<path>" возникает ошибка. Например:

git clone --recurse-submodules --branch=master -j8 \
  https://android.googlesource.com/platform/superproject \
  master
git clone --recurse-submodules --branch=master -j8 \
  https://android.googlesource.com/platform/superproject \
  --reference master master2

не удается с:

fatal: submodule '<snip>' cannot add alternate: reference repository
'<snip>' is shallow

Если альтернатива, вычисленная из альтернативы суперпроекта, не может быть добавлена, будь то в этом или другом случае, посоветуйте настроить параметр « submodule.alternateErrorStrategy» и использовать « --reference-if-able» вместо « --reference» при клонировании.

Это подробно описано в:

В Git 2.25 (Q1 2020) взаимодействие между "git clone --recurse-submodules" и хранилищем альтернативных объектов было плохо разработано.

Doc: объяснение submodule.alternateErrorStrategy

Подписано: Джонатан Тан
Автор: Джефф Кинг

Commit 31224cbdc7clone: альтернативы рекурсивных и опорных опций запускают субмодульные альтернативы», 2016-08-17, Git v2.11.0-rc0 - слияние, перечисленное в пакете № 1 ) научил Git поддерживать параметры конфигурации « submodule.alternateLocation» и « submodule.alternateErrorStrategy» в суперпроекте ,

Если " submodule.alternateLocation" настроен на " superproject" в суперпроекте, всякий раз, когда подмодуль этого суперпроекта клонируется, он вместо этого вычисляет аналогичный альтернативный путь для этого подмодуля из $GIT_DIR/objects/info/alternatesсуперпроекта и ссылается на него.

Опция " submodule.alternateErrorStrategy" определяет, что произойдет, если на эту альтернативу нельзя ссылаться.
Тем не менее, не ясно, что клон работает так, как если бы не был указан альтернативный вариант, если для этого параметра не задано значение «die» (как видно из тестов в 31224cbdc7 ).
Поэтому, документируйте это соответственно.

Документация подмодуля config теперь включает в себя:

submodule.alternateErrorStrategy::

Определяет, как обрабатывать ошибки с альтернативами для подмодуля, вычисленные с помощью submodule.alternateLocation.
Возможные значения ignore, info, die.
По умолчанию это die.
Обратите внимание, что если установлено значение ignoreили info, и если есть ошибка с вычисленной альтернативой, клон будет работать так, как если бы альтернатива не была указана .

VonC
источник
2
Вау, это было быстро! Спасибо за ответ, кстати. Ох и --depthшоудл тоже поспоришь;)
Брайс
3
Казалось бы , что мне совершить fb43e31 запросы недостающее совершать по SHA1 идентификатор, так uploadpack.allowReachableSHA1InWantи uploadpack.allowTipSHA1InWantнастройки на сервере, вероятно , повлияет ли это работает. Сегодня я написал сообщение в список git , в котором указывалось, как использовать мелкие подмодули, чтобы они работали лучше для некоторых сценариев, а именно, если commit также является тегом. Давайте подождем и посмотрим.
MvG
2
С недавним добавлением мелкой опции в .gitmodulesработает ли --depth 1опция для ветвей, которые не отслеживают мастер?
CMCDragonkai
2
@CiroSantilli 法轮功 死 六四 事件 法轮功 Спасибо за точность и тест. Я включил ваш комментарий в ответ для большей наглядности и проголосовал за ваш ответ.
VonC
2
Из ответа не ясно, как это сделать в настоящее время. Кроме того, неясно, нужно ли все это каждый раз, когда кто-то клонирует новую копию, или эти настройки разреженных подмодулей становятся частью репозитория, который ссылается на эти подмодули (например, каждое новое обновление клона и подмодуля приводит к проверкам разреженных подмодулей)
Павел Р
26

Git 2.9.0 поддерживает субмодули мелкого клона напрямую, так что теперь вы можете просто позвонить:

git clone url://to/source/repository --recursive --shallow-submodules
KindDragon
источник
2
Эта опция является наиболее многообещающей, но она не работает в git 2.14.1, фиксация подмодуля не отслеживается ни веткой, ни тегом: stackoverflow.com/a/47374702/895245
Сиро Сантилли 冠状 冠状 病 六四 事件 法轮功
1
@CiroSantilli 法轮功 死 六四 事件 法轮功 Убедитесь, что ваш git-сервер также обновлен
KindDragon
Спасибо, я тестировал локально, без сервера и на GitHub, который я не могу обновить :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
У меня та же проблема с использованием GIT 2.20, он не работает, когда субмодуль не на кончике ветви.
Цитрак
16

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

#!/bin/bash
git submodule init
for i in $(git submodule | sed -e 's/.* //'); do
    spath=$(git config -f .gitmodules --get submodule.$i.path)
    surl=$(git config -f .gitmodules --get submodule.$i.url)
    git clone --depth 1 $surl $spath
done
git submodule update
Маурисио Шеффер
источник
Я получаю fatal: reference is not a tree: 88fb67b07621dfed054d8d75fd50672fb26349dfза каждый подмодуль
knocte
@knocte Вы уже видели stackoverflow.com/questions/2144406/git-shallow-submodules/…
Маурисио Шеффер
1
@knocte: я написал свой ответ в 2010 году. Все изменилось. Вы не можете ожидать, что все поддержат все свои ответы. Я отметил текущий действительный ответ как принятый.
Маурисио Шеффер
13
@knocte Это одна из причин, по которой я перестал участвовать в Stackoverflow. У людей такие нереальные ожидания. Это была бы работа на полный рабочий день, чтобы поддерживать каждый из моих 1637 ответов. И затем есть также комментарии, я полагаю, я должен был бы поддержать те же? Посмотрите на даты, вот для чего они. Если вы читаете какой-то блог .NET 2002 года с кодом, использующим ArrayList вместо List, вы бы использовали это? Вы бы потребовали, чтобы автор обновил свой пост? Тот же принцип применяется здесь.
Маурисио Шеффер
1
s / statusquo / progress /
knocte
8

Читая «исходный код» подмодуля git, похоже, он git submodule addможет обрабатывать подмодули, в которых уже есть свои репозитории. В таком случае...

$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
$ git submodule add $remotesub1 $sub1
#repeat as necessary...

Вы хотите убедиться, что требуемый коммит находится в репозитории подмодулей, поэтому убедитесь, что вы установили соответствующий параметр --depth.

Редактировать: Вы можете избежать нескольких клонов субмодулей вручную с последующим одним обновлением:

$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
#repeat as necessary...
$ git submodule update
Райан Грэм
источник
5
Теперь для git 1.8.0 вы больше не можете клонировать репозиторий внутри репозитория. Так что это решение больше не работает.
Бор
7

Резюме ошибочного / неожиданного / раздражающего поведения на Git 2.14.1

  1. shallow = trueв .gitmodulesзатрагивает только git clone --recurse-submodulesесли HEADиз удаленных точек подмодуля в требуемое обязательство, даже если цель коммита указывает ветвь, и даже если вы поставите branch = mybranchна.gitmodules а.

    Локальный тестовый скрипт . Такое же поведение на GitHub 2017-11, где HEADуправляется настройкой репо филиала по умолчанию:

    git clone --recurse-submodules https://github.com/cirosantilli/test-shallow-submodule-top-branch-shallow
    cd test-shallow-submodule-top-branch-shallow/mod
    git log
    # Multiple commits, not shallow.
    
  2. git clone --recurse-submodules --shallow-submodulesне выполняется , если обязательство не является ни ссылается ответвления или метки с сообщением: error: Server does not allow request for unadvertised object.

    Локальный тестовый скрипт . Такое же поведение на GitHub:

    git clone --recurse-submodules --shallow-submodules https://github.com/cirosantilli/test-shallow-submodule-top-sha
    # error
    

    Я также спросил в списке рассылки: https://marc.info/?l=git&m=151863590026582&w=2 и получил ответ:

    В теории это должно быть легко. :)

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

    Протокол Wire поддерживает запрос точных значений sha1s, так что это должно быть охвачено. (Предостережение: это работает только в том случае, если оператор сервера включает uploadpack.allowReachableSHA1InWant, для которого github не имеет AFAICT)

    git-fetch позволяет извлекать произвольный sha1, поэтому в качестве обходного пути вы можете запустить выборку после рекурсивного клона с помощью «git submodule update», так как он будет использовать выборки после начального клона.

Тест TODO: allowReachableSHA1InWant.

Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
источник
Кажется, что просто не существует простого способа извлечения хэша отдельного коммита HEAD для подмодуля, и иметь нижестоящих пользователей, git clone --recursiveкоторые выбирают только этот конкретный коммит.
CMCDragonkai
3

Канонические места для ваших подмодулей удалены? Если да, то можете ли вы клонировать их один раз? Другими словами, хотите ли вы мелкие клоны только потому, что вы страдаете от потери пропускной способности частых субмодульных (ре) клонов?

Если вы хотите, чтобы мелкие клоны сохраняли локальное дисковое пространство, тогда ответ Райана Грэма выглядит хорошим способом. Вручную клонировать репозитории, чтобы они были мелкими. Если вы думаете, что это будет полезно, адаптируйтесь, git submoduleчтобы поддержать его. Отправить письмо в список просьбой об этом (советы по его реализации, предложения по интерфейсу и т. Д.). По моему мнению, люди вполне поддерживают потенциальных участников, которые искренне хотят улучшить Git конструктивным образом.

Если вы в порядке с выполнением одного полного клона каждого подмодуля (плюс более поздние выборки, чтобы поддерживать их актуальность), вы можете попытаться использовать --referenceопцию git submodule update(это в Git 1.6.4 и более поздних версиях) для ссылки на локальные хранилища объектов (например, создайте --mirrorклоны из канонических репозиториев подмодулей, затем используйте их --referenceв своих подмодулях, чтобы указать на эти локальные клоны). Просто не забудьте прочитать о git clone --reference/ git clone --sharedперед использованием --reference. Единственная вероятная проблема со ссылками на зеркала - это если они когда-нибудь получат обновления без ускоренной пересылки (хотя вы можете включить повторные журналы и расширить их окна истечения срока действия, чтобы помочь сохранить любые оставленные коммиты, которые могут вызвать проблему). У вас не должно быть никаких проблем, пока

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

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

И, как git cloneговорится на странице руководства , не используйте, --referenceесли вы не понимаете этих последствий.

# Full clone (mirror), done once.
git clone --mirror $sub1_url $path_to_mirrors/$sub1_name.git
git clone --mirror $sub2_url $path_to_mirrors/$sub2_name.git

# Reference the full clones any time you initialize a submodule
git clone $super_url super
cd super
git submodule update --init --reference $path_to_mirrors/$sub1_name.git $sub1_path_in_super
git submodule update --init --reference $path_to_mirrors/$sub2_name.git $sub2_path_in_super

# To avoid extra packs in each of the superprojects' submodules,
#   update the mirror clones before any pull/merge in super-projects.
for p in $path_to_mirrors/*.git; do GIT_DIR="$p" git fetch; done

cd super
git pull             # merges in new versions of submodules
git submodule update # update sub refs, checkout new versions,
                     #   but no download since they reference the updated mirrors

В качестве альтернативы --referenceвы можете использовать зеркальные клоны в сочетании с функцией жестких ссылок по умолчанию git clone, используя локальные зеркала в качестве источника для ваших подмодулей. В новых клонах супер-проекта выполните git submodule initредактирование URL-адресов субмодуля, .git/configчтобы они указывали на локальные зеркала, а затем выполнитеgit submodule update . Вам нужно будет отложить любые существующие проверенные подмодули, чтобы получить жесткие ссылки. Вы бы сэкономили пропускную способность, загрузив только один раз в зеркала, а затем загрузив локально из них в свои проверенные подмодули. Жесткое связывание позволит сэкономить дисковое пространство (хотя выборки будут иметь тенденцию накапливаться и дублироваться в нескольких экземплярах хранилищ объектов извлеченных подмодулей; вы можете периодически отгибать извлеченные подмодули из зеркал, чтобы восстановить экономию дискового пространства, обеспечиваемую hardlinking).

Крис Джонсен
источник
2

Я создал немного другую версию, когда она не работает на переднем крае, что не все проекты делают. Стандартные дополнения к субмодулям не работали, как и скрипт выше. Поэтому я добавил поиск хеша для тега ref, и если у него его нет, он возвращается к полному клонированию.

#!/bin/bash
git submodule init
git submodule | while read hash name junk; do
    spath=$(git config -f .gitmodules --get submodule.$name.path)
    surl=$(git config -f .gitmodules --get submodule.$name.url)
    sbr=$(git ls-remote --tags $surl | sed -r "/${hash:1}/ s|^.*tags/([^^]+).*\$|\1|p;d")
    if [ -z $sbr ]; then
        git clone $surl $spath
    else
        git clone -b $sbr --depth 1 --single-branch $surl $spath
    fi
done
git submodule update 
sfossen
источник
2

Ссылка на Как клонировать git-репозиторий с определенной ревизией / набором изменений?

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

git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'

Это утверждение будет извлекать ссылочную версию субмодуля.

Это быстро, но вы не можете зафиксировать ваши изменения в подмодуле (вы должны получить его до отмены https://stackoverflow.com/a/17937889/3156509 )

в полном объеме:

#!/bin/bash
git submodule init
git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'
git submodule update --recursive
Бино Тунг
источник
1

Мелкий клон подмодуля идеален, потому что они делают снимок при определенной ревизии / наборе изменений. Скачать zip с сайта очень просто, поэтому я попробовал скрипт.

#!/bin/bash
git submodule deinit --all -f
for value in $(git submodule | perl -pe 's/.*(\w{40})\s([^\s]+).*/\1:\2/'); do
  mysha=${value%:*}
  mysub=${value#*:}
  myurl=$(grep -A2 -Pi "path = $mysub" .gitmodules | grep -Pio '(?<=url =).*/[^.]+')
  mydir=$(dirname $mysub)
  wget $myurl/archive/$mysha.zip
  unzip $mysha.zip -d $mydir
  test -d $mysub && rm -rf $mysub
  mv $mydir/*-$mysha $mysub
  rm $mysha.zip
done
git submodule init

git submodule deinit --all -f очищает дерево подмодулей, что позволяет использовать скрипт.

git submoduleизвлекает 40 символов sha1, за которыми следует путь, соответствующий тому же значению in .gitmodules. Я использую Perl для объединения этой информации, разделенной двоеточием, а затем использую преобразование переменных для разделения значений на myshaи mysub.

Это критические ключи, потому что нам нужен sha1 для загрузки и путь для корреляции urlв .gitmodules.

Учитывая типичную запись субмодуля:

[submodule "label"]
    path = localpath
    url = https://github.com/repository.git

myurlКлючи path =затем выглядит 2 строки после, чтобы получить значение. Этот метод может не работать последовательно и требует доработки. Grep url удаляет все оставшиеся .gitссылки на типы, сопоставляя их с последним /и любым до ..

mydirэто mysubминус окончательной , /nameкоторый будет каталог , ведущим к имени подмодуль.

Далее идет wgetс форматом загружаемого zip архива url. Это может измениться в будущем.

Разархивируйте файл, в mydirкоторый будет находиться подкаталог, указанный в пути к субмодулю. Результирующая папка будет последним элементом url- sha1.

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

mv переименуйте извлеченную папку, содержащую наш sha1, в правильный путь к субмодулю.

Удалить загруженный почтовый файл.

Подмодуль init

Это скорее подтверждение концепции, а не решение. Когда это работает, результатом является неглубокий клон подмодуля с указанным набором изменений.

Если в хранилище повторно размещен субмодуль для другой фиксации, повторно запустите скрипт для обновления.

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

noabody
источник