运行git拉过所有的子目录
如何从共享父目录中更新多个git存储库,而不必cd
到每个repo的根目录? 我有以下这些都是单独的git仓库( 不是子模块):
/plugins/cms /plugins/admin /plugins/chart
我想一次更新它们,或者至less简化我目前的工作stream程:
cd ~/plugins/admin git pull origin master cd ../chart git pull
等等
在这种情况下从父目录, plugins
运行以下:
find . -type d -depth 1 -exec git --git-dir={}/.git --work-tree=$PWD/{} pull origin master \;
澄清:
-
find .
search当前目录 -
-type d
查找目录,而不是文件 -
-depth 1
表示一个子目录的最大深度 -
-exec {} \;
为每个查找运行自定义命令 -
git --git-dir={}/.git --work-tree=$PWD/{} pull
git pull个人目录
为了玩弄发现,我推荐使用echo
after -exec
预览,例如:
find . -type d -depth 1 -exec echo git --git-dir={}/.git --work-tree=$PWD/{} status \;
注意:如果-depth 1
选项不可用,请尝试-mindepth 1 -maxdepth 1
。
ls | xargs -I{} git -C {} pull
要并行执行:
ls | xargs -P10 -I{} git -C {} pull
比利奥的解决scheme更低技术:
for i in */.git; do ( echo $i; cd $i/..; git pull; ); done
这将更新工作目录中的所有Git存储库。 不需要明确列出他们的名字(“cms”,“admin”,“chart”)。 “cd”命令只影响一个子shell(使用括号产生)。
这应该会自动发生,只要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
我使用这个:
find . -name ".git" -type d | sed 's/\/.git//' | xargs -P10 -I{} git -C {} pull
通用:更新当前目录下的所有git存储库。
mr
实用程序(aka, myrepos
)为这个问题提供了一个出色的解决scheme。 使用你最喜欢的包pipe理器来安装它,或者直接从github中获取mr
脚本,并把它放在$HOME/bin
或PATH
上的其他地方。 然后, cd
到由这些repos共享的父plugins
文件夹,并创build一个基本的.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'
之后,您可以从顶级plugins
文件夹运行mr up
以从每个存储库中提取更新。 (注意,如果目标工作副本还不存在,这也将执行初始克隆)。其他可以执行的命令包括mr st
, mr push
, mr log
, mr diff
,etc mr help
查看可能的结果。 有一个mr run
命令作为pass-through,允许你访问不是直接由mr
VCS命令(例如, mr run git tag STAGING_081220015
)。 而且你甚至可以创build自己的自定义命令来执行任意位的shell脚本来定位所有的回购站!
mr
是一个非常有用的工具来处理多个回购。 由于plugins
文件夹位于您的主目录中,因此您可能也对vcsh
感兴趣。 与mr
一起,它提供了一个pipe理所有configuration文件的强大机制。 请参阅Thomas Ferris Nicolaisen的博客文章 。
最紧凑的方法,假设所有子目录都是git回购:
ls | parallel git -C {} pull
其实,如果你不知道子文件夹是否有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 }
你可以试试这个
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" \;
前5个答案都没有为我工作,问题谈论目录。
这工作:
for d in *; do pushd $d && git pull && popd; done
原始答案2010:
如果所有这些目录都是独立的git回购,你应该引用它们作为子模块 。
这意味着你的“起源”将是那个只包含subrepos'cms',' admin
',' chart
'引用的远程repo“ plugins
”。
一个git pull
然后git submodule update
将实现你正在寻找的东西。
2016年1月更新:
使用Git 2.8(2016年第1季度),您将能够使用git fetch --recurse-submodules -j2
并行获取子模块(!)。
请参阅“ 如何使用git clone –recursive来加速/并行下载git子模块? ”
gitfox
是一个在所有subrepos上执行命令的工具
npm install gitfox -g g pull
我用这个
for dir in $(find . -name ".git") do cd ${dir%/*} echo $PWD git pull echo "" cd - > /dev/null done
Github上
既然你有一个共享的父目录,你可以简单的做
git do pull
插件/目录
我结合了几点意见和答案的观点:
find . -maxdepth 1 -type d -name .git -execdir git pull \;
我谦卑的build设
- 显示当前path(使用python,方便而且正常工作,请参阅如何获取文件的完整path? )
- 直接查看
.git
子文件夹:在非git子文件夹中发出git命令的机会很less - 摆脱一些
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 \;
如果你有很多使用git仓库的subdirs,你可以使用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 '