Skip to content

Instantly share code, notes, and snippets.

@davidwebca
Last active December 11, 2023 16:01
Show Gist options
  • Save davidwebca/c8a4c538f94c453ecd6a1d05757438ef to your computer and use it in GitHub Desktop.
Save davidwebca/c8a4c538f94c453ecd6a1d05757438ef to your computer and use it in GitHub Desktop.
git-ftp rsync hook
#!/bin/bash
remote="$1"
originalurl="$2"
# I created this bash script to hook with git-ftp since the .git-ftp-include mecanism
# doesn't remove files on the remote host which often leads to undesired results.
#
# The script needs a .git-ftp-rsync file at the root of your git repo and a simple
# line-by-line list of folders you want to sync. The .git-ftp-rsync file is a very
# rudimentary one and does not understand the standard .gitignore syntaxes.
# Just a plain folders list, one line after the other!
#
# Then, place this script file in your git hooks folder - /.git/config/hooks/post-ftp-push
# and don't forget to add the execution permissions to it with chmod +x post-ftp-push
#
# We unfortunately receive a weird format from git-ftp and the password is obfuscated
# Since rsync assumes you're using ssh anyway, we parse the url to remove "sftp://" and ":***"
#
# You can use your ~/.ssh/config file to set your remote password, port or key if necessary
# Doing so also removes the requirement of specifying them in your git-ftp configs anwyay
#
# @see https://gist.github.com/joshisa/297b0bc1ec0dcdda0d1625029711fa24?permalink_comment_id=3602499#gistcomment-3602499
#
# Update 2023-12-11: I've added the ability to set local to remote folder so that you're not forced to upload your
# local directory structure.
# Ex: ```public/:web/wow/``` will upload your local ```public/``` folder to ```web/wow/``` on the remote
# You also have the ability to put a colon with an empty right side to target the root of the remote (no need to add slash or ".")
# Ex.: ```public:``` Will simply upload your ```public``` to root of the git-ftp remote directory
# Ignore if .git-ftp-rsync doesn't exist
git_ftp_rsync_file=.git-ftp-rsync
if [[ -f "$git_ftp_rsync_file" ]]; then
protocol=$(echo "$originalurl" | grep "://" | sed -e's,^\(.*://\).*,\1,g')
url_no_protocol=$(echo "${originalurl/$protocol/}")
protocol=$(echo "$protocol" | tr '[:upper:]' '[:lower:]')
userpass=$(echo "$url_no_protocol" | grep "@" | cut -d"/" -f1 | rev | cut -d"@" -f2- | rev)
pass=$(echo "$userpass" | grep ":" | cut -d":" -f2)
if [ -n "$pass" ]; then
user=$(echo "$userpass" | grep ":" | cut -d":" -f1)
else
user="$userpass"
fi
hostport=$(echo "${url_no_protocol/$userpass@/}" | cut -d"/" -f1)
host=$(echo "$hostport" | cut -d":" -f1)
port=$(echo "$hostport" | grep ":" | cut -d":" -f2)
path=$(echo "$url_no_protocol" | grep "/" | cut -d"/" -f2-)
# .git-ftp-include with rsync over ssh
grep -v '^#' "$git_ftp_rsync_file" | {
while read folder; do
# Ignoring empty lines
if [ -n "$folder" ]; then
if [[ "$folder" == *":"* ]]; then
localfolder=$(echo "$folder" | grep ":" | cut -d":" -f1)
remotefolder=$(echo "$folder" | grep ":" | cut -d":" -f2)
else
localfolder="$folder"
remotefolder="$folder"
fi
if [ -d "$localfolder" ]; then
syncurl="$user@$host:/$path$remotefolder"
echo ".git-ftp-rsync - Syncing: $localfolder to $syncurl"
# Rsync Version
rsync -ahv -e "ssh -p $port" "$localfolder" "$syncurl" --delete
# SSH + Scp version
# If rsync doesn't exist, such as on some shared hosts,
# we simply use regular ssh to remove the folder and upload everything
# ssh "$user@$host" "rm -rf /$path$remotefolder && mkdir -p /$path$remotefolder"
# scp -r "$localfolder/." $syncurl
else
echo ".git-ftp-rsync - Folder does not exist: $localfolder"
fi
fi
done
}
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment