Мы используем подмодули git для управления парой больших проектов, которые имеют зависимости от многих других библиотек, которые мы разработали. Каждая библиотека представляет собой отдельное репо, внесенное в зависимый проект в качестве подмодуля. Во время разработки мы часто хотим просто взять последнюю версию каждого зависимого подмодуля.
Есть ли в git встроенная команда для этого? Если нет, то как насчет пакетного файла Windows или чего-то подобного, который может это сделать?
Если вы *впервые проверяете репозиторий, вам нужно сначала использовать --init
:
git submodule update --init --recursive
Для git 1.8.2 и выше была добавлена опция --remote
для поддержки обновления до последних советов удаленных веток:
git submodule update --recursive --remote
Это имеет дополнительное преимущество, поскольку уважает любые "ветви не по умолчанию", указанные в файлах .gitmodules
или .git/config
(если у вас есть такие ветви, по умолчанию это origin/master, в этом случае некоторые из других ответов здесь также будут работать).
Для git 1.7.3 и выше вы можете использовать (но нижеприведенные проблемы с тем, что делать при обновлении, все еще применимы):
git submodule update --recursive
или:
git pull --recurse-submodules
если вы хотите притягивать свои подмодули к последним коммитам, а не к тому, на что указывает репозиторий.
Подробности смотрите в git-submodule(1).
git pull --recurse-submodules --jobs=10
функция ЖКТ впервые узнал в 1.8.5.
В первый раз вам нужно запустить
в Git подмодуля обновление --инит --рекурсивные
git submodule update --init --recursive
в каталог git РЕПО, работает лучше для меня.
Это будет тянуть все последние, включая подмодулей.
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 РЕПО, работает лучше для меня.
Это будет тянуть все последние, включая подмодулей.
Примечание: Эта статья написана в 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, вам может потребоваться изменить синтаксис, чтобы заставить его работать :)
Обновление:
В ответ на замечание оригинального автора о том, что нужно вытащить все HEAD'ы всех подмодулей - это хороший вопрос.
Я уверен, что git
не имеет внутренней команды для этого. Для того, чтобы сделать это, вам нужно определить, что HEAD действительно является HEAD для подмодуля. Это может быть так же просто, как сказать master
- это самая актуальная ветвь и т.д...
После этого создайте простой скрипт, который делает следующее:
git submodule status
для "измененных" репозиториев. Первый символ выходных строк указывает на это. Если подрепозиторий изменен, вы можете не продолжать.git checkout master && git pull
. Проверьте, нет ли ошибок.Я'хотел бы отметить, что этот стиль не совсем то, для чего были разработаны подмодули git. Обычно вы хотите сказать "БиблиотекаX" находится в версии "2.32" и будет оставаться такой, пока я не скажу ей "обновить".
Это, в некотором смысле, то, что вы делаете с помощью описанного сценария, но только более автоматически. Требуется осторожность!
Обновление 2:.
Если вы работаете на платформе windows, вы можете рассмотреть возможность использования Python для реализации скрипта, так как он обладает большими возможностями в этих областях. Если вы работаете на unix/linux, то я предлагаю просто bash-скрипт.
Нужны какие-либо пояснения? Просто напишите комментарий.
Хенрик находится на правильном пути. В 'по объекту' команда может выполнить любой произвольный скрипт. Два варианта, чтобы вытащить самые последние, может быть,
git submodule foreach git pull origin master
и,
git submodule foreach /path/to/some/cool/script.sh
Что будет перебирать все инициализировать подмодули и выполнения данной команды.
Как он может предположить, что ветвь по умолчанию подмодули-это не мастер
, это, как мне автоматизировать полный в 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'
Редактировать:
В комментариях было указано (по philfreo ), что требуется последняя версия. Если есть какие-либо вложенные подмодулей, которые должны быть в последней версии :
git submodule foreach --recursive git pull
-----Устаревший комментарий ниже-----
Это'т это официальный способ сделать это ?
git submodule update --init
Я использую его каждый раз. Никаких проблем пока нет.
Редактировать:
Я просто показал, что вы можете использовать:
git submodule foreach --recursive git submodule update --init
Которая также будет рекурсивно вытащить все подмодули, т. е. зависимостям.
Клон и подмодуль инициализации
git clone [email protected]:speedovation/kiwi-resources.git resources
git submodule init
Во время разработки просто вытащить и обновить субмодуль
git pull --recurse-submodules && git submodule update --recursive
git submodule foreach git pull origin master
git submodule update --remote --merge
Примечание: последние две команды имеют одинаковое поведение
Я не'т знаю, с какой версии Git это работает, но это's то, что вы'вэ искал:
git submodule update --recursive
Я использую его с ГИТ тянуть
, чтобы обновить корень репозитория, тоже:
git pull && git submodule update --recursive
Вышеуказанные ответы хороши, но мы были с использованием git-крючки, чтобы сделать это проще, но получается, что в мерзавец 2.14, вы можете установить ГИТ конфиг субмодуль.рекурсия
True включает подмодули, чтобы обновляться, когда вы тянете в свой репозиторий Git.
Это будет иметь побочный эффект расталкивая всех подмодулей изменения вы если однако они находятся на ветках, но если вам нужно такое поведение уже это может сделать работу.
Может быть сделано с помощью:
git config submodule.recurse true
Из верхнего уровня в репо:
git submodule foreach git checkout develop
git submodule foreach git pull
Это позволит переключать все филиалы разрабатывать и последний потянет
Я сделал это путем адаптации gahooa'ы ответ выше:
Интегрировать его с помощью Git [псевдоним]
...
Если ваш родительский проект имеет нечто подобное в .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
У меня есть пример в настройка среды РЕПО.
Вот командной строки, чтобы вытащить из всех ваших Git-репозитории ли они're или не подмодули:
ROOT=$(git rev-parse --show-toplevel 2> /dev/null)
find "$ROOT" -name .git -type d -execdir git pull -v ';'
Если вы используете его в ваш топ репозитория Git, вы можете заменить в "$корень"
в в .
.
Я думаю, вам придется написать сценарий для этого. Честно говоря, я бы установил для этого python, чтобы вы могли использовать os.walk
для cd
в каждый каталог и выдавать соответствующие команды. Использование python или другого языка сценариев, кроме batch, позволит вам легко добавлять/удалять подпроекты без необходимости изменять сценарий.
Замечание: не слишком простой способ, но выполнимый, и он имеет свои уникальные плюсы.
Если хотите клонировать только "голова" ревизия репозитория и только головы всех его подмодулей (т. е. до выезда на "багажник", У), то можно использовать следующие Луа сценарий. Иногда простая команда в Git подмодуля обновление --инит --рекурсивный --дистанционное --нет-принеси-глубина=1 может привести к ошибка неисправимая
ГИТ. В этом случае нужно убирать подкаталог
.каталог git/модули и подмодули клон вручную с помощью команды git клон --отдельные-ГИТ-реж команду. Единственная сложность заключается в том, чтобы выяснить, *адрес*, путь
.в Git из подмодуля и путь подмодуль в дерево суперпроекты.
Замечание: скрипт протестирован только против https://github.com/boostorg/boost.git
хранилище. Его особенности: все подмодули размещенный на том же хосте и `.gitmodules содержит только относительные адресы.
-- 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