Простой способ получить последние из всех подмодулей git - PullRequest
1627 голосов
/ 23 июня 2009

Мы используем подмодули git для управления парой крупных проектов, которые зависят от многих других библиотек, которые мы разработали. Каждая библиотека представляет собой отдельный репозиторий, внесенный в зависимый проект в виде подмодуля. Во время разработки мы часто хотим просто взять последнюю версию каждого зависимого подмодуля.

Есть ли в git встроенная команда для этого? Если нет, то как насчет пакетного файла Windows или аналогичного, который может это сделать?

Ответы [ 19 ]

2147 голосов
/ 23 июня 2009

Если в первый раз , вы оформляете репо, вам необходимо сначала использовать --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)

599 голосов
/ 10 ноября 2011

Если вам нужно вытащить материал для субмодулей в свои репозитории субмодулей, используйте

git pull --recurse-submodules

особенность, впервые изученная в 1.7.3.

Но это не будет проверять правильные коммиты (те, на которые указывает ваш главный репозиторий) в подмодулях

Чтобы проверить правильность фиксации в ваших подмодулях, вы должны обновить их после извлечения, используя

git submodule update --recursive --remote
366 голосов
/ 11 декабря 2014

При инициализации выполняется следующая команда:

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, лучше всего подходит для меня.

Это будет тянуть все последние, включая подмодули.

302 голосов
/ 23 июня 2009

Примечание: это с 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 на самом деле для подмодуля. Это может быть так же просто, как сказать, что master является самой современной веткой и т. Д. *

После этого создайте простой скрипт, который выполняет следующие действия:

  1. проверьте git submodule status для «модифицированных» репозиториев. Первый символ выходных строк указывает на это. Если суб-репо изменен, вы НЕ МОЖЕТЕ продолжить.
  2. для каждого из перечисленных репо, перейдите в его каталог и запустите git checkout master && git pull. Проверьте на ошибки.
  3. В конце я предлагаю вам распечатать дисплей для отображения текущего статуса субмодулей - возможно, предложить им добавить все и зафиксировать?

Я хотел бы отметить, что этот стиль не совсем то, для чего были созданы подмодули git. Как правило, вы хотите сказать, что «LibraryX» имеет версию «2.32» и будет оставаться такой до тех пор, пока я не скажу «обновить».

Это в некотором смысле то, что вы делаете с описанным сценарием, но просто более автоматически. Требуется осторожность!

Обновление 2:

Если вы работаете на платформе Windows, вы можете захотеть использовать Python для реализации скрипта, так как он очень эффективен в этих областях. Если вы используете unix / linux, то я предлагаю просто скрипт bash.

Нужны пояснения? Просто оставьте комментарий.

154 голосов
/ 23 июня 2009

Хенрик на правильном пути. Команда 'foreach' может выполнить любой произвольный скрипт оболочки. Два варианта, чтобы вытащить самый последний, может быть,

git submodule foreach git pull origin master

и

git submodule foreach /path/to/some/cool/script.sh

Он будет перебирать все инициализированные подмодули и запускать данные команды.

143 голосов
/ 22 июля 2011

У меня на Windows сработало следующее.

git submodule init
git submodule update
33 голосов
/ 05 апреля 2011

Редактировать

В комментариях было указано ( philfreo ), что требуется последняя версия Если есть вложенные подмодули, которые должны быть в их последней версии:

git submodule foreach --recursive git pull

----- устаревший комментарий ниже -----

Разве это не официальный способ сделать это?

git submodule update --init

Я использую это каждый раз. Пока проблем нет.

Edit:

Я только что обнаружил, что вы можете использовать:

git submodule foreach --recursive git submodule update --init 

, который также будет рекурсивно извлекать все подмодули, т.е. зависимости.

31 голосов
/ 04 декабря 2013

Так как может случиться, что веткой по умолчанию ваших подмодулей является , а не 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'
25 голосов
/ 17 сентября 2015

Первый раз

Подмодуль клонирования и инициализации

git clone git@github.com: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

примечание: последние две команды имеют одинаковое поведение

18 голосов
/ 30 сентября 2011

Не знаю, с какой версии git это работает, но вы ищете:

git submodule update --recursive

Я использую его вместе с git pull для обновления корневого хранилища:

git pull && git submodule update --recursive
...