3

On my home machine, I use the script gitpull.sh to concurrently pull all the changes to the git repos under a given directory.

#!/usr/bin/bash

find $1 -name ".git" | sed -r 's|/[^/]+$||' | parallel git -C {} pull origin master

My problem is that parallel is not installed on my work computer. Is it possible to alter my script without the use of parallel?

  • do you have GNU findutils on your work computer? or something else that provides xargs? if so, you can write a version of your gitpull.sh that pipes the sed output into a shell function that does something like xargs -I{} git pull -C {} origin master &. – cas Jan 04 '18 at 08:40
  • Is the reason why you do not have GNU Parallel covered by http://oletange.blogspot.com/2013/04/why-not-install-gnu-parallel.html? If not, please elaborate. – Ole Tange Jan 05 '18 at 04:26

3 Answers3

2

Instead of parallel you could use xargs with the -P flag. Something like:

find $1 -name ".git" | sed -r 's|/[^/]+$||' | xargs -I {} -n 1 -P 0 git -C {} pull origin master
2

You can use this tool Git-Plus to concurrently pull all the changes to the git repos under a given directory. Use this command

$ git multi pull

You can easily install it and use it .

Jai Prak
  • 121
1

You can do it using only bash, readlink, and find:

#!/bin/bash

while IFS= read -d '' -r g ; do 
  dir="$(readlink -f "$g/..")"
  git pull -C "$dir" origin master &
done < <(find "$@" -name '.git' -print0)

You can make it run a bit faster with careful use of find's -maxdepth option. e.g. if you know that all .git directories are going to be found only in the top-level sub-directories of the current directory, -maxdepth 3 will stop it recursing into any lower sub-directories.

I've used "$@" with the find command rather than the unquoted $1 you used so that not only is a directory argument optional, you can use multiple directory args and/or add whatever find options you might need to the command line.

If the version of find on your work computer doesn't do -print0, you can use \n as the input separator, but the script will break if any directory names contain a newline (which is uncommon but perfectly valid).

while IFS= read -r g ; do 
  dir="$(readlink -f "$g/..")"
  git pull -C "$dir" origin master &
done < <(find "$@" -name '.git')
cas
  • 78,579