Схоже, два різних сценарії змішуються в цій дискусії:
Сценарій 1
Використовуючи вказівники мого батьківського репозиторію на підмодулі, я хочу перевірити фіксацію у кожному підмодулі, на який вказує батьківське сховище, можливо після першої ітерації через усі підмодулі та їх оновлення / витягування з віддаленого.
Це, як вказувалося, робиться з
git submodule foreach git pull origin BRANCH
git submodule update
Сценарій 2, на який, на мою думку, спрямований ОП
У одному або декількох підмодулях трапляються нові речі, і я хочу 1) здійснити ці зміни та 2) оновити батьківський сховище, щоб вказати на головну (останню) фіксацію цього / цих підмодулів.
Це було б зроблено до
git submodule foreach git pull origin BRANCH
git add module_1_name
git add module_2_name
......
git add module_n_name
git push origin BRANCH
Не дуже практично, оскільки вам доведеться жорстко кодувати n шляхів до всіх n підмодулів, наприклад, скрипт для оновлення покажчиків фіксації батьківського репозиторію.
Було б здорово мати автоматизовану ітерацію через кожен підмодуль, оновивши покажчик батьківського сховища (використовуючи git add
), щоб вказати на голову підмодуля (ів).
Для цього я створив цей маленький сценарій Баша:
git-update-submodules.sh
#!/bin/bash
APP_PATH=$1
shift
if [ -z $APP_PATH ]; then
echo "Missing 1st argument: should be path to folder of a git repo";
exit 1;
fi
BRANCH=$1
shift
if [ -z $BRANCH ]; then
echo "Missing 2nd argument (branch name)";
exit 1;
fi
echo "Working in: $APP_PATH"
cd $APP_PATH
git checkout $BRANCH && git pull --ff origin $BRANCH
git submodule sync
git submodule init
git submodule update
git submodule foreach "(git checkout $BRANCH && git pull --ff origin $BRANCH && git push origin $BRANCH) || true"
for i in $(git submodule foreach --quiet 'echo $path')
do
echo "Adding $i to root repo"
git add "$i"
done
git commit -m "Updated $BRANCH branch of deployment repo to point to latest head of submodules"
git push origin $BRANCH
Щоб запустити його, виконайте
git-update-submodules.sh /path/to/base/repo BRANCH_NAME
Розробка
Перш за все, я припускаю, що гілка з назвою $ BRANCH (другий аргумент) існує у всіх сховищах. Сміливо зробіть це ще складнішим.
Перша пара розділів - це деяка перевірка наявності аргументів. Потім я перетягую останні матеріали батьківського репозиторію (я вважаю за краще використовувати --ff (швидке переадресація) кожного разу, коли я просто роблю перетягування. У мене відновлюється база, BTW).
git checkout $BRANCH && git pull --ff origin $BRANCH
Тоді може знадобитися ініціалізація підмодуля, якщо нові підмодулі були додані або ще не ініціалізовані:
git submodule sync
git submodule init
git submodule update
Потім я оновлюю / витягую всі підмодулі:
git submodule foreach "(git checkout $BRANCH && git pull --ff origin $BRANCH && git push origin $BRANCH) || true"
Зауважте кілька речей: Перш за все, я прив'язую декілька команд Git, &&
тобто попередня команда повинна виконуватись без помилок.
Після можливого успішного потягу (якщо на пульті дистанційного пошуку знайдено новий матеріал), я роблю поштовх, щоб гарантувати, що можлива злиття-фіксація не залишиться поза клієнтом. Знову ж таки, це трапляється лише в тому випадку, якщо потяг дійсно приніс нові речі.
Нарешті, фінал || true
- це те, щоб сценарій продовжувався на помилках. Щоб зробити цю роботу, все в ітерації повинно бути загорнене в подвійні лапки, а команди Git - в дужках (пріоритет оператора).
Моя улюблена частина:
for i in $(git submodule foreach --quiet 'echo $path')
do
echo "Adding $i to root repo"
git add "$i"
done
Ітерація всіх підмодулів - з --quiet
, що видаляє вихід "MODULE_PATH". Використовуючи 'echo $path'
(має бути в одних лапках), шлях до підмодулю записується на вихід.
Цей список відносних шляхів субмодуля захоплюється в масив ( $(...)
) - остаточно повторіть це і зробіть git add $i
для оновлення батьківського сховища.
Нарешті, команда з деяким повідомленням, що пояснює, що батьківське сховище оновлено. Ця фіксація буде ігнорована за замовчуванням, якщо нічого не було зроблено. Надішліть це на початок, і ви закінчите.
У мене є сценарій, який виконує цю роботу в роботі Дженкінса, яка приєднується до запланованого автоматизованого розгортання після цього, і це працює як шарм.
Я сподіваюся, що це комусь допоможе.
--remote
опцію, можливо, було б корисно відзначити це як прийняту відповідь, а не підхід "від руки" у відповіді Джейсона?