Skip to content

Instantly share code, notes, and snippets.

@phillf
Forked from peterjc/mirror_git
Created July 14, 2019 17:05
Show Gist options
  • Save phillf/d5c2333ab03ef5749a833bd267365b8b to your computer and use it in GitHub Desktop.
Save phillf/d5c2333ab03ef5749a833bd267365b8b to your computer and use it in GitHub Desktop.
Script to push git changes to a mirror repository using a deploy key
#!/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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment