Есть ли способ заставить 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 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 г.)

Коммит 48072e3clone: установить 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;"

Любые предложения по автоматическому запуску команд или псевдонима?

Другие вопросы по тегам