Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@peterjc
Last active September 8, 2021 16:44
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save peterjc/eccac1942a9709993040425d33680352 to your computer and use it in GitHub Desktop.
Save peterjc/eccac1942a9709993040425d33680352 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
@peterjc
Copy link
Author

peterjc commented Jun 25, 2021

This has been superseded by https://gist.github.com/peterjc/899a6d24badd47d6305ddc5e299fd4bd which uses the GitHub API with a personal access token allowing it find repositories and add the deployment keys automatically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment