Команда git plumbing для получения удаленного субмодуля
Я работаю с git plumbing и зеркальными (и, следовательно, голыми) репозиториями в файловой системе только для чтения.
Я могу видеть существование субмодулей с git ls-tree
, Я могу вывести их имя / путь и SHA1, но не могу найти способ получить удаленный субмодуль.
Информация где-то там; если я клонирую репо, git submodule init
преуспевает. (Создание клона слишком дорого для обычного использования, особенно для очень больших репозиториев.) Как я могу получить доступ к удаленному субмодулю напрямую?
1 ответ
Резюме
Начать с git config --blob HEAD:.gitmodules --list
и идти оттуда. Для этого нужны версии Git>= 1.8.4. Обратите внимание, что HEAD
может быть любая ревизия.
Длинная форма и объяснение
Комментарии превратились в ответ, большая часть ответа предоставлена ФП.:-) Кроме того, у нас есть следующие самоссылочные определения: суперпроект - это Git-репозиторий, который имеет подмодули, а подмодуль (иногда также называемый подпроектом) - это Git-репозиторий, управляемый суперпроектом. Сам подмодуль обычно сохраняется извлеченным при определенной фиксации (то есть как "отсоединенный HEAD"), хотя в настоящее время существуют особые случаи, когда вы можете указать Git переключить подмодуль на именованную ветвь. Если подмодуль имеет дополнительные подмодули, "внешний" подмодуль является суперпроектом для "внутреннего" подмодуля, поэтому super/sub все относительно.
Подмодули - URL-адреса хранилища и пути их извлечения - предоставляются файлом с именем .gitmodules
в корневом каталоге суперпроекта. Следовательно, в голом хранилище вы можете получить или извлечь .gitmodules
файл. Этот файл отформатирован как файл конфигурации, поэтому его можно прочитать через git config --file
,
Начиная с Git версии 2.0, вы можете использовать псевдоним -
сослаться на stdin, так:
git show HEAD:.gitmodules | git config --file - --list
выгрузит содержимое в привычном формате. (Если ваш вариант Git старше этого, но у вас есть /dev/stdin
, ты можешь читать /dev/stdin
Вот.)
Оказывается, что есть еще более простой способ: git config
может, начиная с Git версии 1.8.4, читать BLOB-объекты прямо из хранилища. Идентификатор BLOB-объекта является приемлемым для git rev-parse
, который может обрабатывать не только имя ветви или идентификатор фиксации, но даже последующее имя пути. (Этот код специально предназначен для обработки подмодулей: см. https://github.com/git/git/commit/1bc888193e1044db317a45b9a4c8d2b87b998f40.)
подробности
Если задан путь подмодуля P, то имя подмодуля будет зависеть от того, какая запись имеет submodule.name.path
установить на P. Тогда URL для этого подмодуля submodule.name.url
,
Можно найти нужное имя, используя git config --get-regexp
, Однако в лучшем случае это раздражает, так как мы должны затем заключать в кавычки компоненты пути, которые являются метасимволами регулярного выражения, с очевидным общим .
:
$ git config --blob HEAD:.gitmodules \
--get-regexp 'submodule\..*\.path' 'some/dir\.name/path'
submodule.foo.path some/dir.name/path
так что, вероятно, имеет больше смысла просто сбросить конфигурацию с --list
и использовать что-то еще, чтобы извлечь интересные поля. Например:
git config --blob HEAD:.gitmodules --list | \
awk -F= -vpath='some/dir.name/path' \
'$1 ~ /submodule\..*\.path/ && $2 == path { split($1, a, "."); print a[2] }'
(хотя к тому времени, когда вы помещаете это во что-то, что может читать деревья в поисках gitlinks, вы, вероятно, захотите Python или что-то подобное).
Начиная с git v2.x вы можете использовать следующее:
git config --file .gitmodules --get-regexp 'submodule\.\S+\.path' |
awk '{print $2}' |
xargs -i git -C {} remote get-url origin
Объяснение
- 1-я и 2-я команды возвращают относительные пути всех подмодулей
- 3-я команда выполняет
git remote
внутри каталогов подмодулей и получает URL-адрес их происхождения
NB
- удаленные имена для подмодулей должны быть "origin" (установлены git как удаленное имя по умолчанию)
- подмодули должны быть инициализированы раньше (например, путем выполнения
git submodule update --init
внутри суперпроекта)