#!/bin/bash # Enable strict bash mode - halts on any error set -euo pipefail # Takes exactly three command line arguments: git_dir=$1 ssh_key=$2 log_file=$3 #Start new log file echo "$(date) Running git mirror script for ${git_dir}" > $log_file if [ ! -d "${git_dir}/.git" ]; then echo "ERROR: The ${git_dir}/.git directory does not exist" >> $log_file exit 1 fi if [ ! -f "${ssh_key}" ]; then echo "ERROR: The ${ssh_key} SSH key file does not exist" >> $log_file exit 1 fi cd ${git_dir} # Check the origin and mirror remotes exist if [ ! `git remote | grep origin` ]; then echo "ERROR: No origin remote repository to pull from" >> $log_file exit 1 fi if [ ! `git remote | grep mirror` ]; then echo "ERROR: No mirror remote repository to push to" >> $log_file echo "(Did you run 'git fetch mirror' yet?)" >> $log_file exit 1 fi # Might as well check our local copy of origin is current: echo "$(date) Fetching from origin..." >> $log_file git fetch origin --tags >> $log_file 2>&1 if [ ! `git branch -a | grep remotes/origin/master` ]; then echo "ERROR: No origin/master to pull from" >> $log_file exit 1 fi #Wait until setup ssh script and fetch mirror in case this is #the first time the mirroring script has been run and noone #has done a "git fetch mirror" yet: #if [ ! `git branch -a | grep remotes/mirror/master` ]; then # echo "ERROR: No mirror/master to push to" >> $log_file # exit 1 #fi # Create ssh wrapper script using the specified key, i.e. # #!/bin/bash # ssh -i /path/to/key -F /dev/null -p 22 $* # Will use $GIT_SSH to get git to use this SSH key via -i argument, # while -F ensures any ~/.ssh/config settings are ignored. if [ -f "mirror_ssh" ]; then rm -f "mirror_ssh" fi touch "mirror_ssh" echo "#!/bin/bash" >> "mirror_ssh" echo "ssh -i ${ssh_key} -F /dev/null -p 22 \$*" >> "mirror_ssh" chmod u+x "mirror_ssh" # Ensure git will use ssh with our GitHub Deploy Key: export GIT_SSH="${git_dir}/mirror_ssh" if [ ! -x $GIT_SSH ]; then echo "ERROR: Failed to setup ssh wrapper script to use key" >> $log_file exit 1 fi echo "$(date) Setup git ssh script" >> $log_file # Might as well check our local copy of mirror is current, # and possible there has been no fetch since doing # git remote add mirror ... echo "$(date) Fetching from mirror..." >> $log_file git fetch mirror --tags >> $log_file 2>&1 if [ ! `git branch -a | grep remotes/mirror/master` ]; then echo "ERROR: No mirror/master to push to" >> $log_file exit 1 fi # Make sure we're on the master branch: git reset --hard >> $log_file 2>&1 git checkout master >> $log_file 2>&1 # Get the latest changes from the original repository # (Using fast forward only means this will fail if # the git history was rewritten - which would likely # need reviewing rather than blindly mirroring) echo "$(date) Fetching from origin..." >> $log_file # Already did fetch origin, could do merge --ff-only: git pull --ff-only origin master >> $log_file 2>&1 # Push the lastest changes to the master branch on our # mirror repository (write access via GitHub Deploy Key) echo "$(date) Pushing to mirror..." >> $log_file git push mirror master --tags >> $log_file 2>&1 echo "$(date) GitHub mirror sync done." >> log_file