Легкий способ вытащить последние из всех подмодулей git
Мы используем подмодули git для управления парой крупных проектов, которые зависят от многих других библиотек, которые мы разработали. Каждая библиотека представляет собой отдельный репозиторий, внесенный в зависимый проект в виде подмодуля. Во время разработки мы часто хотим просто взять последнюю версию каждого зависимого подмодуля.
Есть ли в git встроенная команда для этого? Если нет, то как насчет пакетного файла Windows или аналогичного, который может это сделать?
Ответы
Ответ 1
Если вы в первый раз --init
репо, вам сначала нужно использовать --init
:
git submodule update --init --recursive
Для git 1.8.2 или выше была добавлена опция --remote
для поддержки обновления до последних подсказок удаленных веток:
git submodule update --recursive --remote
Это дает дополнительное преимущество, .gitmodules
в уважении любых веток "не по умолчанию", указанных в .gitmodules
или .git/config
(если они у вас есть, по умолчанию это origin/master, и в этом случае некоторые другие ответы здесь будут работать как Что ж).
Для git 1.7.3 или выше вы можете использовать (но ниже приведены некоторые вопросы о том, какое обновление по-прежнему применяется):
git submodule update --recursive
или же:
git pull --recurse-submodules
если вы хотите вытащить свои подмодули к последним коммитам, на что указывает репо.
Смотрите git-submodule (1) для подробностей
Ответ 2
git pull --recurse-submodules --jobs=10
Git впервые узнал в 1.8.5.
В первый раз вам нужно запустить
git submodule update --init --recursive
Ответ 3
На init запускается следующая команда:
git submodule update --init --recursive
из каталога git repo лучше всего работает для меня.
Это потянет все последние, включая подмодули.
Разъяснения
git - the base command to perform any git command
submodule - Inspects, updates and manages submodules.
update - Update the registered submodules to match what the superproject
expects by cloning missing submodules and updating the working tree of the
submodules. The "updating" can be done in several ways depending on command
line options and the value of submodule.<name>.update configuration variable.
--init without the explicit init step if you do not intend to customize
any submodule locations.
--recursive is specified, this command will recurse into the registered
submodules, and update any nested submodules within.
После этого вы можете просто запустить:
git submodule update --recursive
из каталога git repo лучше всего работает для меня.
Это будет тянуть все последние, включая подмодули.
Ответ 4
Примечание. Это с 2009 года, возможно, было хорошо, но теперь есть лучшие варианты.
Мы используем это. Он назывался git-pup
:
#!/bin/bash
# Exists to fully update the git repo that you are sitting in...
git pull && git submodule init && git submodule update && git submodule status
Просто поместите его в соответствующий каталог bin (/usr/local/bin). Если в Windows вам может потребоваться изменить синтаксис, чтобы заставить его работать:)
Update:
В ответ на комментарий оригинального автора о том, чтобы вытащить все главы всех подмодулей - это хороший вопрос.
Я уверен, что git
не имеет для этого команды. Для этого вам нужно будет определить, что такое HEAD для субмодуля. Это может быть так же просто, как сказать, что master
- самая современная ветка и т.д.
После этого создайте простой script, который выполняет следующие действия:
- проверить
git submodule status
для "измененных" репозиториев. Это указывает первый символ выходных строк. Если подрепо будет изменено, вы НЕ захотите продолжить.
- для каждого зарегистрированного репо, cd в его каталог и запустите
git checkout master && git pull
. Проверьте наличие ошибок.
- В конце я предлагаю вам распечатать дисплей пользователю, чтобы указать текущий статус подмодулей - возможно, предложите им добавить все и совершить?
Я хотел бы упомянуть, что этот стиль на самом деле не был разработан для подмодулей git. Как правило, вы хотите сказать, что "LibraryX" находится в версии "2.32" и останется таким, пока я не скажу "обновить".
То есть, в некотором смысле, то, что вы делаете с описанным script, но просто более автоматически. Требуется помощь!
Обновление 2:
Если вы находитесь на платформе Windows, вам может понадобиться использовать Python для реализации script, поскольку он очень способен в этих областях. Если вы используете unix/linux, я предлагаю только bash script.
Нужны какие-либо разъяснения? Просто отправьте комментарий.
Ответ 5
Хенрик находится на правильном пути. Команда foreach может выполнять любую произвольную оболочку script. Возможны две возможности:
git submodule foreach git pull origin master
и
git submodule foreach /path/to/some/cool/script.sh
Это будет проходить через все инициализированные подмодули и запускать заданные команды.
Ответ 6
Следующие действия работали для меня в Windows.
git submodule init
git submodule update
Ответ 7
Edit
В комментариях было указано (philfreo), что требуется последняя версия. Если есть какие-либо вложенные подмодули, которые должны быть в их последней версии:
git submodule foreach --recursive git pull
----- Устаревший комментарий ниже -----
Разве это не официальный способ сделать это?
git submodule update --init
Я использую его каждый раз. На данный момент проблем нет.
Edit:
Я только что нашел, что вы можете использовать:
git submodule foreach --recursive git submodule update --init
который также рекурсивно вытащит все подмодули, т.е. зависимости.
Ответ 8
Как может случиться так, что ветвь ваших подмодулей по умолчанию не master
, вот как я могу автоматизировать обновление модулей Git:
git submodule init
git submodule update
git submodule foreach 'git fetch origin; git checkout $(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'
Ответ 9
Первый раз
Подкомпоны клона и Init
git clone [email protected]:speedovation/kiwi-resources.git resources
git submodule init
Отдых
Во время разработки просто вытащите и обновите подмодуль
git pull --recurse-submodules && git submodule update --recursive
Обновить подмодуль Git для последнего фиксации по происхождению
git submodule foreach git pull origin master
Предпочтительный путь должен быть ниже
git submodule update --remote --merge
Примечание: последние две команды имеют одинаковое поведение
Ответ 10
Я не знаю, с какой версии git это работает, но это то, что вы ищете:
git submodule update --recursive
Я использую его с git pull
для обновления корневого репозитория:
git pull && git submodule update --recursive
Ответ 11
Приведенные выше ответы хороши, однако мы использовали git-hooks, чтобы сделать это проще, но получается, что в git 2.14 вы можете установить для git config submodule.recurse
значение true, чтобы включить подмодули для обновляется, когда вы загружаете в свой репозиторий git.
Это будет иметь побочный эффект, когда вы будете менять все подмодули, которые у вас есть, если они находятся на ветках, но если вам уже нужно такое поведение, это может помочь.
Можно сделать с помощью:
git config submodule.recurse true
Ответ 12
Посмотрите http://lists.zerezo.com/git/msg674976.html, в котором вводится параметр -track
Ответ 13
Git для Windows 2.6.3:
git submodule update --rebase --remote
Ответ 14
Я сделал это, адаптировав gahooa ответ выше:
Интегрируйте его с помощью git [alias]
...
Если ваш родительский проект имеет что-то вроде этого в .gitmodules
:
[submodule "opt/submodules/solarized"]
path = opt/submodules/solarized
url = [email protected]:altercation/solarized.git
[submodule "opt/submodules/intellij-colors-solarized"]
path = opt/submodules/intellij-colors-solarized
url = [email protected]:jkaving/intellij-colors-solarized.git
Добавьте что-то подобное в свой .gitconfig
[alias]
updatesubs = "!sh -c \"git submodule init && git submodule update && git submodule status\" "
Затем, чтобы обновить ваши подмодули, запустите:
git updatesubs
У меня есть пример в моем настройка настройки среды.
Ответ 15
С верхнего уровня в репо:
git submodule foreach git checkout develop
git submodule foreach git pull
Это переключит все ветки на разработку и загрузку последних
Ответ 16
Вот командная строка, которая вытаскивает из всех ваших репозиториев git, являются ли они или нет подмодулями:
ROOT=$(git rev-parse --show-toplevel 2> /dev/null)
find "$ROOT" -name .git -type d -execdir git pull -v ';'
Если вы запустите его в своем верхнем хранилище git, вы можете заменить "$ROOT"
на .
.
Ответ 17
Все, что вам нужно сделать сейчас, это простая git checkout
Просто убедитесь, что он git config --global submodule.recurse true
помощью этой глобальной конфигурации: git config --global submodule.recurse true
Ответ 18
Думаю, вам нужно написать script, чтобы сделать это. Честно говоря, я мог бы установить python для этого, чтобы вы могли использовать os.walk
to cd
для каждого каталога и выдавать соответствующие команды. Использование python или другого языка сценариев, кроме пакета, позволит вам легко добавлять/удалять подпроекты без необходимости изменять script.
Ответ 19
Примечание: не слишком простой способ, но работоспособный, и у него есть свои уникальные профи.
Если вы хотите клонировать только ревизию репозитория HEAD
и только HEAD
всех своих подмодулей (т.е. для проверки "trunk" ), тогда можно использовать следующую Lua script. Иногда простая команда git submodule update --init --recursive --remote --no-fetch --depth=1
может привести к невосстановимой ошибке git
. В этом случае необходимо вручную очистить подкаталог каталога .git/modules
и подмодулировать клон с помощью команды git clone --separate-git-dir
. Единственная сложность заключается в том, чтобы узнать URL-адрес каталога .git
подмодуля и путь подмодуля в дереве суперпроектов.
Примечание: script проверяется только на репозитории https://github.com/boostorg/boost.git
. Его особенности: все подмодули, размещенные на одном и том же хосте, и .gitmodules
содержат только относительные URL-адреса.
-- mkdir boost ; cd boost ; lua ../git-submodules-clone-HEAD.lua https://github.com/boostorg/boost.git .
local module_url = arg[1] or 'https://github.com/boostorg/boost.git'
local module = arg[2] or module_url:match('.+/([_%d%a]+)%.git')
local branch = arg[3] or 'master'
function execute(command)
print('# ' .. command)
return os.execute(command)
end
-- execute('rm -rf ' .. module)
if not execute('git clone --single-branch --branch master --depth=1 ' .. module_url .. ' ' .. module) then
io.stderr:write('can\'t clone repository from ' .. module_url .. ' to ' .. module .. '\n')
return 1
end
-- cd $module ; git submodule update --init --recursive --remote --no-fetch --depth=1
execute('mkdir -p ' .. module .. '/.git/modules')
assert(io.input(module .. '/.gitmodules'))
local lines = {}
for line in io.lines() do
table.insert(lines, line)
end
local submodule
local path
local submodule_url
for _, line in ipairs(lines) do
local submodule_ = line:match('^%[submodule %"([_%d%a]-)%"%]$')
if submodule_ then
submodule = submodule_
path = nil
submodule_url = nil
else
local path_ = line:match('^%s*path = (.+)$')
if path_ then
path = path_
else
submodule_url = line:match('^%s*url = (.+)$')
end
if submodule and path and submodule_url then
-- execute('rm -rf ' .. path)
local git_dir = module .. '/.git/modules/' .. path:match('^.-/(.+)$')
-- execute('rm -rf ' .. git_dir)
execute('mkdir -p $(dirname "' .. git_dir .. '")')
if not execute('git clone --depth=1 --single-branch --branch=' .. branch .. ' --separate-git-dir ' .. git_dir .. ' ' .. module_url .. '/' .. submodule_url .. ' ' .. module .. '/' .. path) then
io.stderr:write('can\'t clone submodule ' .. submodule .. '\n')
return 1
end
path = nil
submodule_url = nil
end
end
end