如何在没有cd
进入每个repo的根目录的情况下,从共享父目录更新多个git存储库?我有以下几个单独的git存储库(不子模块):
/plugins/cms
/plugins/admin
/plugins/chart
我想一次更新所有内容,或者至少简化我当前的工作流程:
cd ~/plugins/admin
git pull origin master
cd ../chart
git pull
等
答案 0 :(得分:256)
在这种情况下,从父目录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拉出各个目录要使用find,我建议在echo
之后使用-exec
进行预览,例如:
find . -type d -depth 1 -exec echo git --git-dir={}/.git --work-tree=$PWD/{} status \;
注意:如果-depth 1
选项不可用,请尝试-mindepth 1 -maxdepth 1
。
答案 1 :(得分:149)
ls | xargs -I{} git -C {} pull
要并行执行:
ls | xargs -P10 -I{} git -C {} pull
答案 2 :(得分:42)
比leo的解决方案更低技术性:
for i in */.git; do ( echo $i; cd $i/..; git pull; ); done
这将更新工作目录中的所有Git存储库。无需明确列出他们的名字(" cms"," admin"," chart")。 " cd"命令仅影响子shell(使用括号生成)。
答案 3 :(得分:18)
我用这个:
find . -name ".git" -type d | sed 's/\/.git//' | xargs -P10 -I{} git -C {} pull
Universal:更新当前目录下的所有git存储库。
答案 4 :(得分:13)
实际上,如果您不知道子文件夹是否有git repo,最好让element
为您获取回购:
find
PowerShell的等价物是:
find . -type d -name .git -exec git --git-dir={} --work-tree=$PWD/{}/.. pull origin master \;
答案 5 :(得分:11)
这应该是自动发生的,只要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
答案 6 :(得分:11)
mr
实用程序(a.k.a。,myrepos
)为此问题提供了杰出解决方案。使用您最喜欢的软件包管理器安装它,或者只需抓取mr
脚本directly from github并将其放在$HOME/bin
或PATH
上的其他位置。然后,cd
到这些repos共享的父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
,{{1} }等等 - 运行mr diff
以查看可能的内容。有mr help
命令作为传递,允许您访问不由mr run
本身直接支持的VCS命令(例如mr
)。您甚至可以创建自己的自定义命令,执行针对所有repos的任意shell脚本!
mr run git tag STAGING_081220015
是处理多个回购的极其有用的工具。由于mr
文件夹位于您的主目录中,因此您可能也对vcsh
感兴趣。与plugins
一起,它提供了一个强大的机制来管理所有配置文件。请参阅Thomas Ferris Nicolaisen的blog post作为概述。
答案 7 :(得分:10)
最紧凑的方法,假设所有子目录都是git repos:
ls | parallel git -C {} pull
答案 8 :(得分:4)
前5个答案中没有一个适合我,问题涉及目录。
这有效:
for d in *; do pushd $d && git pull && popd; done
答案 9 :(得分:4)
gitfox
是一个在所有子目录上执行命令的工具
npm install gitfox -g
g pull
答案 10 :(得分:2)
你可以试试这个
find . -type d -name .git -exec sh -c "cd \"{}\"/../ && pwd && git pull" \;
此外,您还可以添加一个&amp;&amp;&amp;这样的论点。
find . -type d -name .git -exec sh -c "cd \"{}\"/../ && pwd && git pull && git status" \;
答案 11 :(得分:1)
2010年原始答案:
如果所有这些目录都是单独的git repo,您应该将它们引用为 submodules 。
这意味着您的“来源”将是远程回购“plugins
”,其仅包含对子展位“cms
”,“admin
”,“chart
”的引用
git pull
后跟git submodule update
可以实现您的目标。
2016年1月更新:
使用Git 2.8(2016年第一季度),您将能够使用git fetch --recurse-submodules -j2
并行(!)获取子模块。
请参阅“How to speed up / parallelize downloads of git submodules using git clone --recursive?”
答案 12 :(得分:1)
我的谦逊建筑
.git
子文件夹:在非git子文件夹中发出git命令的可能性很小find
如下:
find . \
-maxdepth 2 -type d \
-name ".git" \
-execdir python -c 'import os; print(os.path.abspath("."))' \; \
-execdir git pull \;
当然,您可以向-execdir
添加其他带有find
选项的git命令,例如显示分支:
find . \
-maxdepth 2 -type d \
-name ".git" \
-execdir python -c 'import os; print(os.path.abspath("."))' \; \
-execdir git branch \;
-execdir git pull \;
答案 13 :(得分:0)
我用这个
for dir in $(find . -name ".git")
do cd ${dir%/*}
echo $PWD
git pull
echo ""
cd - > /dev/null
done
答案 14 :(得分:0)
我将几个评论和答案的要点结合起来:
find . -maxdepth 1 -type d -name .git -execdir git pull \;
答案 15 :(得分:-1)
如果你有很多带有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
'