Run git pull over all subdirectories [duplicate]
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 (not submodules):
/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.
Run the following from the parent directory, plugins
in this case:
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 find -
git --git-dir={}/.git --work-tree=$PWD/{} pull
git pulls the individual directories
To play around with find, I recommend using echo
after -exec
to preview, e.g.:
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
.
ls | xargs -I{} git -C {} pull
To do it in parallel:
ls | xargs -P10 -I{} git -C {} pull
A bit more low-tech than leo's solution:
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).
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:
find . -type d -name .git -exec git --git-dir={} --work-tree=$PWD/{}/.. pull origin master \;
The PowerShell equivalent would be:
Get-ChildItem -Recurse -Directory -Hidden -Filter .git | ForEach-Object { & git --git-dir="$($_.FullName)" --work-tree="$(Split-Path $_.FullName -Parent)" pull origin master }
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.