Published 2023-03-11.
Last modified 2025-10-03.
Time to read: 2 minutes.
git collection.
I need to keep several hundred git repositories up-to-date.
I have a directory tree of website repos, and a directory tree of code repos.
Updating these trees was tedious until I wrote the initial version of the
update script back in 2008.
Environment Variables
/etc/environment is a system-wide configuration file, which is
sourced
every time a user logs in.
It is owned by root, so your account needs to be a member of the admin group,
or you will have to use sudo to modify it.
The /etc/environment file in all of my systems defines two environment variables:
sites- Points to the root of the website directory tree
work- Points to the root of the code project tree
export sites=/var/www export work=/var/work
Now $sites and $work will be defined for all users every time they log in.
In addition, I define subordinate environment variables for each project in a file called $work/.evars
export cadenzaHome=$work/cadenzaHome
export cadenzaCode=$cadenzaHome/cadenzaCode
export cadenzaDependencies=$cadenzaCode/cadenzaDependencies
export awslib_scala=$cadenzaDependencies/awslib_scala
export shoppingcart=$cadenzaDependencies/shoppingcart
export clients=$work/clients
export django=$work/django
export msp=$sites/www.mslinn.com
...
$work/.evars is included by ~/.bashrc.
source $work/.evars
Switching Directories
The above environment variables allow me to easily move to a Git project directory without having to remember where it resides on the computer that I am currently using:
$ cd $clients
$ pwd /var/work/clients
Updating Git Directory Trees
I first wrote a Bash version of a command I called update,
years later I wrote a multithreaded Ruby version that runs orders of magnitude faster for large directory trees.
I called this version git-update; note that it requires a properly set up
Ruby development environment.
The site and work environment variables are used by the update scripts.
#!/bin/bash
# Update all git directories below current directory or specified directory
# Skips directories that contain a file called .ignore
# See https://stackoverflow.com/a/61207488/553865
if [ "$( curl -sL -w "%{http_code}\n" https://www.github.com -o /dev/null )" != 200 ]; then
echo "Cannot connect to GitHub"
exit 2
fi
HIGHLIGHT="\e[01;34m"
NORMAL='\e[00m'
export PATH=${PATH/':./:'/:}
export PATH=${PATH/':./bin:'/:}
#echo "$PATH"
if [ -z "$1" ]; then
ROOTS="$sites $work"
else
ROOTS="$@"
fi
echo "Updating $ROOTS"
DIRS="$( find -L $ROOTS -type d \( -execdir test -e {}/.ignore \; -prune \) -o \( -execdir test -d {}/.git \; -prune -print \) )"
echo -e "${HIGHLIGHT}Scanning ${PWD}${NORMAL}"
for d in $DIRS; do
cd "$d" > /dev/null || exit 2
echo -e "\n${HIGHLIGHT}Updating `pwd`$NORMAL"
git pull
cd - > /dev/null || exit 3
done
The Ruby version of update is waaaay faster than the Bash version!
Install the git-tree gem
and get several git-related commands, including git-update.
💕💕💕
Most of the time I want to update everything in the standard Git directory trees, so for that no arguments are required:
$ git update Updating /var/www /var/work Updating /var/work/cadenzaHome/cadenzaCode/cadenzaDependencies/awslib_scala Already up to date.
Updating /var/work/cadenzaHome/cadenzaCode/cadenzaDependencies/shoppingcart Already up to date.
...
It is also possible to specify the roots of one or more directory trees of git repositories:
$ git update /path/to/another/tree $my_gems $my_plugins Updating /path/to/another/tree /mnt/f/work/ruby/my_gems /mnt/f/work/jekyll/my_plugins
I hope you find the update scripts to be as useful as I have!