Skip to content

Instantly share code, notes, and snippets.

@douglas
Created October 14, 2011 15:04
Show Gist options
  • Save douglas/1287372 to your computer and use it in GitHub Desktop.
Save douglas/1287372 to your computer and use it in GitHub Desktop.
Update all git repositories under a base directory
#!/bin/bash
# store the current dir
CUR_DIR=$(pwd)
# Let the person running the script know what's going on.
echo "\n\033[1mPulling in latest changes for all repositories...\033[0m\n"
# Find all git repositories and update it to the master latest revision
for i in $(find . -name ".git" | cut -c 3-); do
echo "";
echo "\033[33m"+$i+"\033[0m";
# We have to go to the .git parent directory to call the pull command
cd "$i";
cd ..;
# finally pull
git pull origin master;
# lets get back to the CUR_DIR
cd $CUR_DIR
done
echo "\n\033[32mComplete!\033[0m\n"
@bennycode
Copy link

bennycode commented May 30, 2016

Cool stuff! Even runs on Windows 10. 😎

@dmhowcroft
Copy link

What license is associated with this Gist? MIT? Apache? DWTFYW? :)

@nkh
Copy link

nkh commented Oct 27, 2016

dmhowcroft,

Legally anything released without a copyright notice is public domain, the notice contains a year range. If you release something with a year range then a few years later you make changes without updating the copyright notice, then those changes are public domain.

It was nice of you to ask the author :)

@MrMikeyagi
Copy link

MrMikeyagi commented Dec 3, 2016

I have some gits organized with my other gits that no longer have working github pages and so when the script gets to them it asks for a username and password. Is there any way to add to the script to make it so it just enters nothing for both the username and password? (or any other way to make it skip that hangup). I'd like to keep the related gits together for organizational purposes if possible. Thank you so much for your time and this awesome and SUPER USEFUL script :)

EDIT - Also I forgot to add that I put "read" (without the quotes) at the end so I can read the text log before it closes :)

@devCharles
Copy link

devCharles commented Jun 18, 2017

hey guys if you want i have another script here, it follows the same idea here but with many other options, i am a noob so if you have some feedback or want to contribute please let me know :D
https://github.com/devCharles/gitRepoUpdater

@JamesSwift
Copy link

If you want this to work with submodules too, I'd suggest using a slightly altered version of @mndrix's solution:

find . -name .git -type d | xargs -n1 -P4 -I% git --git-dir=% --work-tree=%/.. fetch --all --recurse-submodules

If you need to manually enter passwords for some repos, use this instead:

find . -name .git -type d | xargs -n1 -I% git --git-dir=% --work-tree=%/.. fetch --all --recurse-submodules

The --recurse-submodules options tells git to also fetch commits from any submodules' upstream. It means that if you run this script then go offline and checkout a new version of one of your projects which references a new submodule commit, when you run git submodule update it will be still able to find the new commit.

@agentbellnorm
Copy link

Perfect, thanks!

@haythamdouaihy
Copy link

simple and does what is needed, thank you!

@djangofan
Copy link

#!/bin/bash
# run this from your workspace, which contains all your Git repos
CUR_DIR=$(pwd)
echo "\nUpdating remotes for all repositories...\n"
for i in $(find . -mindepth 1 -maxdepth 1 -type d); do
    printf "\nIn Folder: $i";
    cd "$i";
    printf "\n"
    THIS_REMOTES="$(git remote -v)"
    arr=($THIS_REMOTES)
    OLD_REMOTE="${arr[1]}";
    NEW_REMOTE="${OLD_REMOTE/git.old.net/git.new.org}"
    printf "New remote: $NEW_REMOTE"
    printf "\n"
    git remote set-url origin "$NEW_REMOTE"
    cd $CUR_DIR
done
printf "\nComplete!\n"

@lonely-porcupine
Copy link

Hey guys,

thought about handling cases when there are some changes made in files or any other situation where just git pull won't succeed?

@crowtherdr
Copy link

Very helpful! Thank you

@iancrowther
Copy link

thanks

@Nadeeshyama
Copy link

Thank you, very helpful. 👍

@rigtorp
Copy link

rigtorp commented Sep 19, 2018

Simplest solution to fetch all remotes:

$ find . -name .git -type d -exec git --git-dir '{}' fetch --all ';'

@harisankar-krishna-swamy
Copy link

harisankar-krishna-swamy commented Oct 29, 2018

For all find commands -prune will help save time by not searching inside of .git folders. (find man page mentions this).

find ~/GIT-REPOSITORIES ( -exec test -d '{}'/.git ; ) -print -prune

Pipe from there or so
find ~/GIT-REPOSITORIES ( -exec test -d '{}'/.git ; ) -print -prune | xargs -n1 -I% git --git-dir=%/.git --work-tree=%/ pull --all

@shastrula
Copy link

This is the variation I use:
#To Pull

#!/usr/bin/env bash for repo in $(find . -name ".git" | cut -c 3- | sed 's/.git//g'); do current_branch=git -C ${repo} branch\|grep '*'\|cut -d' ' -f2;echo -e "Pulling repo: ${repo} \t on branch: ${current_branch}"; git -C $repo pull done

#To View

#!/usr/bin/env bash for repo in $(find . -name ".git" | cut -c 3- | sed 's/.git//g'); do current_branch=git -C ${repo} branch\|grep '*'\|cut -d' ' -f2;echo -e "repo: ${repo} \t on branch: ${current_branch}" done

@boyter
Copy link

boyter commented Oct 22, 2019

dmhowcroft,

Legally anything released without a copyright notice is public domain, the notice contains a year range. If you release something with a year range then a few years later you make changes without updating the copyright notice, then those changes are public domain.

It was nice of you to ask the author :)

Actually that's not 100% true but fairly close. Its not possible for Australians or Germans to release anything public domain as neither counties allow citizens to give away their rights. Its one of the reasons its so important to license things.

@joeytwiddle
Copy link

@harisankar-krishna-swamy

find . -maxdepth 8 -name '.git' -prune -type d -printf '%h\n' | parallel --eta 'echo {} && git -C {} pull'

remove echo and --eta if not needed.

@lucasmodrich
Copy link

Works perfectly. Thanks!

@valentin9
Copy link

Thanks!

@jazz-it
Copy link

jazz-it commented Sep 7, 2020

find . -maxdepth 8 -name '.git' -prune -type d -printf '%h\n' | parallel --eta 'echo {} && git -C {} pull'

Very simple, yet effective and blazingly fast. Amazing! Thanks, @harisankar-krishna-2015

@douglas
Copy link
Author

douglas commented Oct 19, 2020

Heh! I had this need again after 9 years and was surprised by the amount of comments =)

Thanks for all suggestions - I will update the gist with improvements to run on macos and Linux 👍

@jensthomsenEV
Copy link

jensthomsenEV commented Mar 9, 2021

How will this work in visual studio code with a workspace setup? I would like to be able to do a pull-from in all the repositories in the workspace, followed by a syncronization, except if there is a merge conflict.

@NorkzYT
Copy link

NorkzYT commented Jun 15, 2022

How will this work in visual studio code with a workspace setup? I would like to be able to do a pull-from in all the repositories in the workspace, followed by a syncronization, except if there is a merge conflict.

Did you find a solution to this or an alternative?

@vhristev
Copy link

Here is a solution for MacOSX:
Im running that from my root repo folder ( no .git in that folder )

~/Documents/repos/
~/Documents/repos/repo1
~/Documents/repos/repo2
/usr/bin/find . -maxdepth 1 -type d -print | parallel --eta 'echo {} && git -C {} pull'

@Andrei-Fogoros
Copy link

Hello @douglas,

Under which license is the above code released?

Thanks in advance! :)

@douglas
Copy link
Author

douglas commented Jan 2, 2024

Hello folks!

New year and just had to use it again - thanks for letting me know about GNU parallel =)

About the license, it is public domain - do whatever you want with it provided the gist is not used in a malicious context 👍

@Andrei-Fogoros
Copy link

Hello folks!

New year and just had to use it again - thanks for letting me know about GNU parallel =)

About the license, it is public domain - do whatever you want with it provided the gist is not used in a malicious context 👍

Thank you very much, Douglas!
Happy New Year! :)

@ramonsmits
Copy link

Had to replace all echo with printf for ANSI color output to work on Fedora 41

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment