Skip to content

Instantly share code, notes, and snippets.

@oodavid
Last active August 6, 2022 10:37
Show Gist options
  • Save oodavid/9c4db85745301c94ca0e to your computer and use it in GitHub Desktop.
Save oodavid/9c4db85745301c94ca0e to your computer and use it in GitHub Desktop.
Execute this file from a local git repo to create repos on your webserver to act as a remote AND working master branch
#!/bin/bash
# This script is no good for servers with multiple-users, I simply
# designed it to quickly push my git tinkerings to my EC2 test server.
#
# Use at your own risk!
#
# cd to a local directory under git control and execute this script, it will:
# create repos on your server
# modify your local remotes to push to the server
# modify your server remotes to push to the same origins as your local
# ...this allows you to shell to the server and tinker as normal, pushing to the same remotes as locally
#
# In a little more detail:
# Creates TWO repos on your server:
# A BARE repo that can is used as a remote
# A WORK repo that sits on the master branch
# The WORK repo has the same ORIGIN remote as your local repo
# The WORK repo has the BARE repo as a remote
# Adds the BARE repo to your local remotes (so `git push server` pushes to the server)
# Creates a post-update hook on the BARE repo, so that:
# When it receives data, the WORK repo pulls it
#
# PREREQUISITES
# Your server should already be configured to comminucate with your
# remotes (github etc.), just follow the usual guides:
# https://help.github.com/articles/set-up-git/
# https://help.github.com/articles/generating-ssh-keys/
# Set these before using
# serverAddress="IPADDRESS"; # Server IP address or CNAME, for SSH
# serverUser="user"; # Server user, for SSH
# serverSites="/home/user"; # Server directory to store sites
# serverRemotes="/home/user/git"; # Server directory to store remote repos
# Preflight
if [[ ! $serverAddress ]]; then echo "\$serverAddress not set"; exit; fi;
if [[ ! $serverUser ]]; then echo "\$serverUser not set"; exit; fi;
if [[ ! $serverSites ]]; then echo "\$serverSites not set"; exit; fi;
if [[ ! $serverRemotes ]]; then echo "\$serverRemotes not set"; exit; fi;
# Must run in a git directory
if [ ! -d .git ]; then
echo 'Script must run in a git directory';
exit;
fi;
# Read the origin
origin=$(git config --get remote.origin.url);
read -p "origin set to \"$origin\", continue? [Y/n] " prompt
if [[ $prompt =~ ^[^yY] ]]; then
echo 'EXIT';
exit;
fi
# Directory names
name="${PWD##*/}";
work="$serverSites/${name}"; # Site REPO
bare="$serverRemotes/${name}.git"; # Remote REPO
# Create a script to run on the server ...unescaped variables are hoisted and expanded
echo "Creating script";
tmpfile="./${name}.servergit.sh";
cat > $tmpfile <<EOF
#!/bin/bash
# Create the BARE repo
mkdir -p "${bare}";
cd "${bare}";
git init --bare;
# Create the WORK repo by cloning from the known origin
mkdir -p "${work}";
cd "${work}";
git clone "$origin" .;
git fetch;
git pull;
git remote add web "${bare}";
git push web master;
# Create the post-update hook so that when BARE receives data, WORK pulls it down
cat > "${bare}/hooks/post-receive" <<HEREDOC
#!/bin/sh
cd "${work}" || exit
unset GIT_DIR
git pull web HEAD
HEREDOC
chmod +x "${bare}/hooks/post-receive";
EOF
# Upload to the server, execute and tidy
echo "--- UPLOADING AND EXECUTING SCRIPT ---";
scp $tmpfile "${serverUser}@${serverAddress}:~";
ssh "${serverUser}@${serverAddress}" "chmod +x ${tmpfile}; ${tmpfile}; rm ${tmpfile};";
rm $tmpfile;
echo "--- FINISHED EXECUTING SCRIPT ON SERVER ---";
# Update the LOCAL repo to push to web
echo "Adding remote locally";
git remote add web "${serverUser}@${serverAddress}:${bare}";
echo "All done! Use 'git push web master' to push to the server :-)";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment