bash 在所有子目录上运行 git pull
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3497123/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Run git pull over all subdirectories
提问by Petah
How can I update multiple git repositories from their shared parent's directory without cd
'ing into each repo's root directory? I have the following which are all separate git repositories (notsubmodules):
如何在不cd
进入每个 repo 的根目录的情况下从其共享父目录更新多个 git 存储库?我有以下都是单独的 git 存储库(不是子模块):
/plugins/cms
/plugins/admin
/plugins/chart
I want to update them all at once or at least simplify my current workflow:
我想一次更新它们或至少简化我当前的工作流程:
cd ~/plugins/admin
git pull origin master
cd ../chart
git pull
etc.
等等。
回答by leo
Run the following from the parent directory, plugins
in this case:
plugins
在本例中,从父目录运行以下命令:
find . -type d -depth 1 -exec git --git-dir={}/.git --work-tree=$PWD/{} pull origin master \;
To clarify:
澄清:
find .
searches the current directory-type d
to find directories, not files-depth 1
for a maximum depth of one sub-directory-exec {} \;
runs a custom command for every findgit --git-dir={}/.git --work-tree=$PWD/{} pull
git pulls the individual directories
find .
搜索当前目录-type d
查找目录,而不是文件-depth 1
一个子目录的最大深度-exec {} \;
为每个查找运行一个自定义命令git --git-dir={}/.git --work-tree=$PWD/{} pull
git 拉取单个目录
To play around with find, I recommend using echo
after -exec
to preview, e.g.:
要玩弄查找,我建议使用echo
after-exec
进行预览,例如:
find . -type d -depth 1 -exec echo git --git-dir={}/.git --work-tree=$PWD/{} status \;
Note: if the -depth 1
option is not available, try -mindepth 1 -maxdepth 1
.
注意:如果该-depth 1
选项不可用,请尝试-mindepth 1 -maxdepth 1
。
回答by Dmitry Mitskevich
ls | xargs -I{} git -C {} pull
To do it in parallel:
要并行执行:
ls | xargs -P10 -I{} git -C {} pull
回答by Ingo Blechschmidt
A bit more low-tech than leo's solution:
比 leo 的解决方案技术含量低一点:
for i in */.git; do ( echo $i; cd $i/..; git pull; ); done
This will update all Git repositories in your working directory. No need to explicitly list their names ("cms", "admin", "chart"). The "cd" command only affects a subshell (spawned using the parenthesis).
这将更新您工作目录中的所有 Git 存储库。无需明确列出他们的名字(“cms”、“admin”、“chart”)。“cd”命令仅影响子shell(使用括号生成)。
回答by Liudvikas
I use this one:
我用这个:
find . -name ".git" -type d | sed 's/\/.git//' | xargs -P10 -I{} git -C {} pull
Universal: Updates all git repositories that are below current directory.
通用:更新当前目录下的所有 git 存储库。
回答by Gildas
Actually, if you don't know if the subfolders have a git repo or not, the best would be to let find
get the repos for you:
实际上,如果您不知道子文件夹是否有 git 存储库,最好让find
您为您获取存储库:
find . -type d -name .git -exec git --git-dir={} --work-tree=$PWD/{}/.. pull origin master \;
The PowerShell equivalent would be:
PowerShell 等效项是:
Get-ChildItem -Recurse -Directory -Hidden -Filter .git | ForEach-Object { & git --git-dir="$($_.FullName)" --work-tree="$(Split-Path $_.FullName -Parent)" pull origin master }
回答by evadeflow
The mr
utility (a.k.a., myrepos
) provides an outstandingsolution to this very problem. Install it using your favorite package manager, or just grab the mr
script directly from githuband put it in $HOME/bin
or somewhere else on your PATH
. Then, cd
to the parent plugins
folder shared by these repos and create a basic .mrconfig
file with contents similar to the following (adjusting the URLs as needed):
该mr
实用程序(又名myrepos
)提供了一个优秀的解决方案,这非常的问题。安装它使用您喜欢的包管理,或只是抢mr
脚本直接从GitHub,并把它$HOME/bin
和别的地方在你的PATH
。然后,cd
到plugins
这些 repos 共享的父文件夹并创建一个.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'
After that, you can run mr up
from the top level plugins
folder to pull updates from each repository. (Note that this will also do the initial clone if the target working copy doesn't yet exist.) Other commands you can execute include mr st
, mr push
, mr log
, mr diff
, etc—run mr help
to see what's possible. There's a mr run
command that acts as a pass-through, allowing you to access VCS commands not directly suported by mr
itself (e.g., mr run git tag STAGING_081220015
). And you can even create your own custom commands that execute arbitrary bits of shell script targeting all repos!
之后,您可以mr up
从顶级plugins
文件夹运行以从每个存储库中提取更新。(注意,这也将做初步克隆如果目标工作副本尚不存在)。你可以执行包括其他命令mr st
,mr push
,mr log
,mr diff
,等运行mr help
,看看什么是可能的。有一个mr run
作为传递的命令,允许您访问mr
本身不直接支持的 VCS 命令(例如,mr run git tag STAGING_081220015
)。您甚至可以创建自己的自定义命令,以执行针对所有存储库的任意位 shell 脚本!
mr
is an extremely useful tool for dealing with multiple repos. Since the plugins
folder is in your home directory, you might also be interested in vcsh
. Together with mr
, it provides a powerful mechanism for managing allof your configuration files. See this blog postby Thomas Ferris Nicolaisen for an overview.
mr
是处理多个 repos 的非常有用的工具。由于该plugins
文件夹位于您的主目录中,您可能还对vcsh
. 与 一起mr
,它提供了一种强大的机制来管理您的所有配置文件。有关概述,请参阅Thomas Ferris Nicolaisen 的这篇博文。
回答by Jamie Wong
This should happen automatically, so long as cms, admin and chart are all parts of the repository.
这应该自动发生,只要 cms、admin 和 chart 都是存储库的一部分。
A likely issue is that each of these plugins is a git submodule.
一个可能的问题是这些插件中的每一个都是一个 git 子模块。
Run git help submodule
for more information.
运行git help submodule
以获取更多信息。
EDIT
编辑
For doing this in bash:
要在 bash 中执行此操作:
cd plugins
for f in cms admin chart
do
cd $f && git pull origin master && cd ..
done
回答by cmcginty
Most compact method, assuming all sub-dirs are git repos:
最紧凑的方法,假设所有子目录都是 git repos:
ls | parallel git -C {} pull
回答by Ryan
None of the top 5 answers worked for me, and the question talked about directories.
前 5 个答案中没有一个对我有用,问题是关于目录的。
This worked:
这有效:
for d in *; do pushd $d && git pull && popd; done
回答by eqfox
gitfox
is a tool to execute command on all subrepos
gitfox
是一个在所有子仓库上执行命令的工具
npm install gitfox -g
g pull