Published 2023-03-11.
Time to read: 1 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
My ~/.bashrc
script defines two environment variables,
each of which point at the root of one of the following directory trees:
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
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
export sites=/var/www export work=/var/work 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
The site
and work
environment variables are used by the update
script:
#!/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
Most of the time I want to update everything in both directory trees, so for that no arguments are required:
$ 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 update an arbitrary directory tree of git repositories:
$ update /path/to/another/tree Updating /path/to/another/tree
I hope you find the update
script as useful as I have!