#!/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