Запустите git потяните все подкаталоги
Как я могу обновить несколько репозиториев git из их общего родительского каталога без cd
"в каждый корневой каталог репо? У меня есть следующие, которые являются отдельными репозиториями git (не):
/plugins/cms
/plugins/admin
/plugins/chart
Я хочу обновить их все сразу или, по крайней мере, упростить текущий рабочий процесс:
cd ~/plugins/admin
git pull origin master
cd ../chart
git pull
и др.
Ответы
Ответ 1
Выполните следующее из родительского каталога plugins
в этом случае:
find . -type d -depth 1 -exec git --git-dir={}/.git --work-tree=$PWD/{} pull origin master \;
Чтобы уточнить:
-
find .
выполняет поиск текущего каталога
-
-type d
для поиска каталогов, а не файлов
-
-depth 1
для максимальной глубины одного подкаталога
-
-exec {} \;
запускает пользовательскую команду для каждого поиска
-
git --git-dir={}/.git --work-tree=$PWD/{} pull
git извлекает отдельные каталоги
Чтобы поиграть с поиском, я рекомендую использовать echo
после -exec
для предварительного просмотра, например:
find . -type d -depth 1 -exec echo git --git-dir={}/.git --work-tree=$PWD/{} status \;
Примечание: если параметр -depth 1
недоступен, попробуйте -mindepth 1 -maxdepth 1
.
Ответ 2
ls | xargs -I{} git -C {} pull
Чтобы сделать это параллельно:
ls | xargs -P10 -I{} git -C {} pull
Ответ 3
Немного более низкотехнологичное, чем лео-решение:
for i in */.git; do ( echo $i; cd $i/..; git pull; ); done
Это обновит все репозитории Git в вашем рабочем каталоге. Не нужно явно перечислять свои имена ( "cms", "admin", "chart" ). Команда "cd" влияет только на подоболочку (порожденную с помощью скобок).
Ответ 4
Это должно происходить автоматически, пока cms, admin и chart - все части репозитория.
Вероятная проблема заключается в том, что каждый из этих плагинов является подмодулем git.
Запустите git help submodule
для получения дополнительной информации.
ИЗМЕНИТЬ
Для этого в bash:
cd plugins
for f in cms admin chart
do
cd $f && git pull origin master && cd ..
done
Ответ 5
Я использую этот:
find . -name ".git" -type d | sed 's/\/.git//' | xargs -P10 -I{} git -C {} pull
Universal: обновляет все репозитории git, которые находятся ниже текущего каталога.
Ответ 6
Утилита mr
(a.k.a., myrepos
) обеспечивает выдающееся решение этой проблемы. Установите его с помощью своего любимого менеджера пакетов или просто возьмите mr
script непосредственно из github и поместите его в $HOME/bin
или в другое место на вашем PATH
. Затем cd
в родительскую папку plugins
, совместно используемую этими репозиториями, и создайте базовый файл .mrconfig
с содержимым, аналогичным следующему (корректируя URL-адреса по мере необходимости):
# File: .mrconfig
[cms]
checkout = git clone 'https://<username>@github.com/<username>/cms' 'cms'
[admin]
checkout = git clone 'https://<username>@github.com/<username>/admin' 'admin'
[chart]
checkout = git clone 'https://<username>@github.com/<username>/chart' 'chart'
После этого вы можете запустить mr up
из верхнего уровня plugins
, чтобы извлекать обновления из каждого репозитория. (Обратите внимание, что это также сделает начальный клон, если целевая рабочая копия еще не существует.) Другие команды, которые вы можете выполнить, включают в себя mr st
, mr push
, mr log
, mr diff
и т.д. mr help
чтобы увидеть, что возможно. Там есть команда mr run
, которая действует как сквозной проход, позволяя вам получать доступ к командам VCS, которые непосредственно не поддерживаются самим mr
(например, mr run git tag STAGING_081220015
). И вы даже можете создавать свои собственные команды, которые выполняют произвольные бит оболочки script, предназначенные для всех репозиций!
mr
- чрезвычайно полезный инструмент для работы с несколькими репозиториями. Поскольку папка plugins
находится в вашем домашнем каталоге, вас также может заинтересовать vcsh
. Вместе с mr
он обеспечивает мощный механизм управления всеми вашими конфигурационными файлами. См. Этот сообщение в блоге от Thomas Ferris Nicolaisen для обзора.
Ответ 7
Самый компактный метод, предполагая, что все поддиректоры git repos:
ls | parallel git -C {} pull
Ответ 8
На самом деле, если вы не знаете, есть ли вложенные папки git repo или нет, лучше всего позволить find
получить репозиции для вас:
find . -type d -name .git -exec git --git-dir={} --work-tree=$PWD/{}/.. pull origin master \;
Эквивалент PowerShell:
Get-ChildItem -Recurse -Directory -Hidden -Filter .git | ForEach-Object { & git --git-dir="$($_.FullName)" --work-tree="$(Split-Path $_.FullName -Parent)" pull origin master }
Ответ 9
Вы можете попробовать это
find . -type d -name .git -exec sh -c "cd \"{}\"/../ && pwd && git pull" \;
Кроме того, вы можете добавить свой индивидуальный вывод, добавив еще один && аргумент вроде.
find . -type d -name .git -exec sh -c "cd \"{}\"/../ && pwd && git pull && git status" \;
Ответ 10
Ни один из 5 лучших ответов не работал у меня, и вопрос касался каталогов.
Это сработало:
for d in *; do pushd $d && git pull && popd; done
Ответ 11
Оригинальный ответ 2010:
Если все эти каталоги являются отдельными репозиториями git, вы должны ссылаться на них как подмодули.
Это означает, что ваше "происхождение" будет таким удаленным репо "plugins
", которое содержит только ссылки на подпозиции "cms
", "admin
", "chart
".
A git pull
, за которым следует a git submodule update
, достигнет того, что вы ищете.
Обновление в январе 2016 года:
С git 2.8 (Q1 2016) вы сможете получить подмодули параллельно (!) с помощью git fetch --recurse-submodules -j2
.
См. "Как ускорить/распараллелить загрузки подмодулей git с помощью git clone --recursive?"
Ответ 12
gitfox
- это инструмент для выполнения команды во всех subppos
npm install gitfox -g
g pull
Ответ 13
Я использую этот
for dir in $(find . -name ".git")
do cd ${dir%/*}
echo $PWD
git pull
echo ""
cd - > /dev/null
done
Github
Ответ 14
Поскольку у вас есть общий родительский каталог, вы можете просто сделать
git do pull
в каталоге plugins/
Ответ 15
Я объединил точки из нескольких комментариев и ответов:
find . -maxdepth 1 -type d -name .git -execdir git pull \;
Ответ 16
Моя скромная конструкция, которая
- показывает текущий путь (используя python, удобно и просто работает, см. Как получить полный путь к файлу?)
- смотрит в подпапку
.git
: низкий шанс исправить команду git в подпапке git
- избавляется от некоторых предупреждений
find
следующим образом:
find . \
-maxdepth 2 -type d \
-name ".git" \
-execdir python -c 'import os; print(os.path.abspath("."))' \; \
-execdir git pull \;
Конечно, вы можете добавить другие команды git с дополнительными параметрами -execdir
в find
, отображая ветвь, например:
find . \
-maxdepth 2 -type d \
-name ".git" \
-execdir python -c 'import os; print(os.path.abspath("."))' \; \
-execdir git branch \;
-execdir git pull \;
Ответ 17
Если у вас много субдисков с репозиториями git, вы можете использовать параллельный
ls | parallel -I{} -j100 '
if [ -d {}/.git ]; then
echo Pulling {}
git -C {} pull > /dev/null && echo "pulled" || echo "error :("
else
echo {} is not a .git directory
fi
'