我如何从他们的共享父目录更新多个git存储库而不__abc0 '到每个repo的根目录?我有以下所有单独的git存储库(不子模块):
/plugins/cms /plugins/admin /plugins/chart
我想一次更新它们,或者至少简化我当前的工作流程:
cd ~/plugins/admin git pull origin master cd ../chart git pull
等。
这应该是自动发生的,只要cms, admin和chart都是存储库的一部分。
一个可能的问题是这些插件都是git子模块。
运行git help submodule获取更多信息。
git help submodule
编辑
在bash中这样做:
cd plugins for f in cms admin chart do cd $f && git pull origin master && cd .. done
2010年原答案:
如果所有这些目录都是独立的git repo,则应该将它们引用为submodules。
这意味着你的“起源”将是远程回购'plugins',它只包含对子回购'cms', 'admin', 'chart'的引用。
plugins
cms
admin
chart
git pull后跟git submodule update将实现你所寻找的。
git pull
git submodule update
2016年1月更新:
git fetch --recurse-submodules -j2
从父目录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
为了更好地使用find,我建议在-exec之后使用echo进行预览,例如:
-exec
echo
find . -type d -depth 1 -exec echo git --git-dir={}/.git --work-tree=$PWD/{} status \;
注意:如果-depth 1选项不可用,请尝试-mindepth 1 -maxdepth 1。
-mindepth 1 -maxdepth 1
比里奥的解决方案更低技术含量:
for i in */.git; do ( echo $i; cd $i/..; git pull; ); done
这将更新工作目录中的所有Git存储库。不需要显式列出他们的名字(“cms”,“admin”,“chart”)。“cd”命令只影响子shell(使用圆括号派生)。
ls | xargs -I{} git -C {} pull
并行地做:
ls | xargs -P10 -I{} git -C {} pull
你可以试试这个
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" \;
如果你有很多git仓库的子dirs,你可以使用parallel
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 '
mr实用程序(也就是myrepos)为这个问题提供了一个杰出的解决方案。使用你最喜欢的包管理器安装它,或者只是抓取mr脚本myrepos0,并将其放在$HOME/bin或你的PATH的其他地方。然后,将cd放到这些repo共享的父文件夹plugins中,并创建一个基本的.mrconfig文件,其内容类似于以下内容(根据需要调整url):
mr
myrepos
$HOME/bin
PATH
cd
.mrconfig
# 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'
之后,你可以从顶层的plugins文件夹运行mr up从每个存储库中提取更新。(注意,如果目标工作副本还不存在,这也会执行初始克隆。)你可以执行的其他命令包括mr st, mr push, mr log, mr diff等——运行mr help来看看有什么可能。有一个mr run命令作为传递,允许你访问mr本身不直接支持的VCS命令(例如,mr run git tag STAGING_081220015)。您甚至可以创建自己的自定义命令,执行针对所有回购的任意shell脚本!
mr up
mr st
mr push
mr log
mr diff
mr help
mr run
mr run git tag STAGING_081220015
mr是处理多个回购的一个非常有用的工具。由于plugins文件夹在你的主目录中,你可能对vcsh也感兴趣。它与mr一起提供了一种强大的机制来管理配置文件的所有。请看Thomas Ferris Nicolaisen的博客概述。
vcsh
最紧凑的方法,假设所有子dirs都是git回购:
ls | parallel git -C {} pull
我用的是这个:
find . -name ".git" -type d | sed 's/\/.git//' | xargs -P10 -I{} git -C {} pull
通用:更新当前目录下的所有git存储库。
我用这个
for dir in $(find . -name ".git") do cd ${dir%/*} echo $PWD git pull echo "" cd - > /dev/null done
Github
前5个答案都不适合我,而且这个问题是关于目录的。
这工作:
for d in *; do pushd $d && git pull && popd; done
实际上,如果你不知道子文件夹是否有一个git repo,最好是让find为你获取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 }
gitfox是一个在所有subrepo上执行命令的工具
gitfox
npm install gitfox -g g pull
我从一些评论和回答中总结了几点:
find . -maxdepth 1 -type d -name .git -execdir git pull \;
我的拙见是
.git
遵循:
find . \ -maxdepth 2 -type d \ -name ".git" \ -execdir python -c 'import os; print(os.path.abspath("."))' \; \ -execdir git pull \;
当然,你可以在find中添加其他带有额外-execdir选项的git命令,显示分支,例如:
-execdir
find . \ -maxdepth 2 -type d \ -name ".git" \ -execdir python -c 'import os; print(os.path.abspath("."))' \; \ -execdir git branch \; -execdir git pull \;