Есть ли способ заставить git pull автоматически обновлять подмодули?
Есть ли способ автоматически иметь git submodule update
(или предпочтительно git submodule update --init
вызывается всякий раз, когда git pull
готово?
Ищите настройки git config или псевдоним git, чтобы помочь с этим.
9 ответов
Начиная с git 2.14, вы можете установить submodule.recurse
в true, чтобы включить желаемое поведение.
Вы можете сделать это глобально, запустив:
git config --global submodule.recurse true
git config --global alias.pullall '!git pull && git submodule update --init --recursive'
Если вы хотите, чтобы аргументы передавались в git pull, используйте вместо этого:
git config --global alias.pullall '!f(){ git pull "$@" && git submodule update --init --recursive; }; f'
Начиная с Git 1.7.5, он должен обновлять подмодули автоматически по умолчанию так, как вы этого хотите.
[РЕДАКТИРОВАТЬ: согласно комментариям: новое поведение 1.7.5 - автоматически извлекать последние коммиты для подмодулей, но не обновлять их (в git submodule update
смысл). Таким образом, информация в этом ответе актуальна как справочная информация, но сама по себе она не является полным ответом. Вам все еще нужен псевдоним, чтобы вытащить и обновить подмодули одной командой.]
Поведение по умолчанию "по требованию" - обновлять субмодули всякий раз, когда вы выбираете коммит, который обновляет коммит субмодуля, а этот коммит еще не находится в вашем локальном клоне.
Вы также можете обновлять его при каждой загрузке или никогда (поведение до версии 1.7.5, я полагаю).
Параметр конфигурации, чтобы изменить это поведение fetch.recurseSubmodules
,
Этот параметр может быть установлен либо на логическое значение, либо на
on-demand
,
Установка его в логическое значение изменяет поведениеfetch
а такжеpull
безоговорочно возвращаться в подмодули, если установлено значение true, или вообще не рекурсировать, если установлено значение false.Когда установлено
on-demand
(значение по умолчанию),fetch
а такжеpull
будет возвращаться в заполненный подмодуль только тогда, когда его суперпроект извлекает коммит, который обновляет ссылку подмодуля.
Увидеть:
git config
Страница man (1.7.5) (или последняяgit config
справочная страница)git fetch
Страница man (1.7.5) (или последняя страница man git fetch)
для дополнительной информации.
git fetch --recurse-submodules[=yes|on-demand|no]
Я удивлен, что никто не упомянул об использовании git hooks для этого!
Просто добавьте файлы с именем post-checkout
а также post-merge
на ваш .git/hooks
каталог соответствующих репозиториев и поместите в каждый из них следующее:
#!/bin/sh
git submodule update --init --recursive
Поскольку вы специально запросили псевдоним, предполагая, что вы хотите иметь его для многих репозиториев, вы можете создать псевдоним, который добавляет их в репозиторий. .git/hooks
для тебя.
Как уже упоминали другие, вы можете легко установить это с помощью:
git config --global submodule.recurse true
Тем не менее, если вы похожи на меня и более сложный .gitconfig
настройка (моя главная ~/.gitconfig
использование файлов include
загрузить в другой .gitconfig
файлы), и вы никогда не сможете вспомнить, как конвертировать между командной строкой git
формат конфигурации и .gitconfig
формат, вот как добавить его в любой из ваших .gitconfig
файлы:
[submodule]
recurse = true
Псевдоним, предложенный Кевином Баллардом, является отличным решением. Просто, чтобы бросить другой вариант, вы также можете использовать хук после слияния, который просто запускается git submodule update [--init]
,
Вы можете создать псевдоним для команды git, которая автоматически обрабатывает обновление субмодуля. Добавьте следующее в ваш.bashrc
# make git submodules usable
# This overwrites the 'git' command with modifications where necessary, and
# calls the original otherwise
git() {
if [[ $@ == clone* ]]; then
gitargs=$(echo "$@" | cut -c6-)
command git clone --recursive $gitargs
elif [[ $@ == pull* ]]; then
command git "$@" && git submodule update --init --recursive
elif [[ $@ == checkout* ]]; then
command git "$@" && git submodule update --init --recursive
else
command git "$@"
fi
}
Начиная с Git 2.15, вы можете установить для submodule.recurse значение true, чтобы обеспечить желаемое поведение.
Собственно, вам и не нужно этого делать.
До Git 2.34 (4 квартал 2021 г.), после "" ( ), все подмодули клонируются, но по умолчанию они не рекурсируются другими командами.
С Git 2.34 и набором настроек
submodule.recurse
конфигурация установлена на
true
в репозитории, созданном с помощью «клона» с опцией «».
См. (14 августа 2021 г.) Махи Колла (
24mahik
) .
(Слияние Junio C Hamano -
gitster
- в коммите 6d09fc5, 10 сентября 2021 г.)
Коммит 48072e3
clone
: установить submodule.recurse = true, если submodule.stickyRecursiveClone включенПодписано: Махи Колла
Основываясь на текущем опыте, при беге
git clone --recurse-submodules
(manman ), разработчики не ожидают, что другие команды, такие как pull или checkout, будут рекурсивно запускаться в активных подмодулях.Однако установка
submodule.recurse=true
на этом этапе можно упростить рабочий процесс, исключив необходимость--recurse-submodules
вариант в последующих командах.Чтобы собрать больше данных о предпочтениях разработчиков в отношении использования submodule.recurse = true в качестве значения конфигурации по умолчанию в будущем, разверните эту функцию с помощью опции opt in
submodule.stickyRecursiveClone
флаг.
Единственный способ, которым я смог обновить подмодули и вложенные подмодули:
git submodule update --remote --merge --recursive; git submodule foreach --recursive "(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);" git add .; git commit -m 'SubmodulesSynced'; git push; git pull;
Мне было сложно создать псевдоним через терминал из-за скобок, поэтому мне пришлось вручную добавить это в.gitconfig для global:
[alias] supdate = "!git submodule update --remote --merge --recursive; git submodule foreach --recursive '(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);' git add .; git commit -m 'SubmodulesSynced'; git push; git pull;"
Любые предложения по автоматическому запуску команд или псевдонима?