How to use a git hook to upload to a website that only allows ftp

NOTE: FIRST SEE THE UPDATE AT THE END FOR A NICER WAY TO DO THIS. USE AT YOUR OWN RISK, THIS WILL PROBABLY DELETE EVERYTHING ON YOUR SERVER AND EAT YOUR GRANDPARENTS!

There absolutely has to be better ways to do this, but with my weak bash-fu and lots of help from the good people on #git I stumbled through and got something working.

I am using gitosis to host a repo that is shared between a couple of people I trust. They have given me their keys and commit via ssh. I just followed the instructions on http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way

I used yafc for the ftp part. It was my first time using it and I love it to bits. No more gui ftp clients for me, or plain old ftp either. The bookmark feature is awesome and really helped me out here.

  1. Login to your site via yafc anc save it as a bookmark
  2. Add the script below to your remote repo i.e. login to the server you are pushing to, if you set it up with gitosis you will have /home/git/repos/YourRepo and put it in hooks/post-receive.
  3. Finally make hooks/post-receive executable to enable it (chmod u+x post-receive)

#!/bin/sh

CHANGES=`mktemp -q -t`
FTPSTAGE=”/home/git/YourRepo-ftp/”

while read oldrev newrev refname
do
# This gets the paths of the files in the repo that have changed
# and shows if they are added A, deleted D etc.
echo `git diff-tree –name-status -r $oldrev $newrev` > “$CHANGES”
echo $CHANGES >> /home/git/YourRepo.log
UPLOADS=`cat “$CHANGES” | grep -v “^D” | cut -d” ” -f2`
# The sed expression here is to convert the path in the repo to the path on the server
DELETES=`cat “$CHANGES” | grep “^D” | cut -d” ” -f2 | sed -e ‘s/^drupal\/YourRepo.website\///g’`
echo `date` “\nUploading: $UPLOADS\nDeleting: $DELETES” >> /home/git/YourRepo-git-ftp.log
for U in $UPLOADS
do
# Again to change the repo path into the server filesystem path
FTPPATH=`echo “$U” | sed -e ‘s/^drupal\/YourRepo.website//g’`
# This dumps the files out of the repo on to the filesystem to be uploaded later
mkdir -p $FTPSTAGE`dirname $FTPPATH`
git cat-file blob $newrev:$U > $FTPSTAGE$FTPPATH
done
done

# Tell yafc to upload everything that has been dumped from the repo
# and delete everything that needs to be deleted
yafc <&lt;**
open YourBookmark
cd /public_html/YourRepo.website
put -fr $FTPSTAGE/*
rm -r $DELETES
close
**

# Tidy up
rm -rf $FTPSTAGE/*

If you’re any good at bash you are probably screaming in disgust right now but if you can spare a minute to explain how to improve this I would be grateful.

Note: this is so lame it doesn’t delete directories that have been created when you delete them from git. It just deletes the files. That’s just because the git command to get the paths doesn’t show when you’ve deleted the directory higher up. It just about works for me now, even though it’s horrible.

UPDATE: Replace all that gubbins with something like the following procedure:
Clone the repo on the server and set up sitecopy to sync that with the live site. Then in the post-receive hook:

cd /path/to/cloned/repo
unset GIT_DIR
git pull
sitecopy -u name

if you don’t change GIT_DIR you’ll see fatal: Not a git repository: ‘.’ even though running the hook on it’s own will work fine.
Thanks to: http://www.mail-archive.com/git@vger.kernel.org/msg03458.html

Advertisements

5 thoughts on “How to use a git hook to upload to a website that only allows ftp”

  1. I tried out sitecopy under Ubuntu 8.10. It’s working well so far with a site with basic cheap webhosting. I would recommend running commands several times if they fail.

  2. I wouldn’t recommend using sitecopy. In my experience it has been unsafe and stupid. Ignoring filenames only ignores wildcards and not paths, so I can’t ignore “tmp” without “tmp2” being ignored. When the upload operation fails or is cancelled half way through, it leaves the site’s data file corrupt (i.e. empty) and thus you lose all your site state. It tries to upload directories that already exists and shows an error rather than recursing through them and adding files inside them where necessary. It’s just generally been a pain in the arse to use.

  3. Thanks Marc, I’m sure there must be a better way now that git has taken over the world, but the solution you offer assumes you have ssh access to the machine (which just makes life too easy by far!). Many cheap web hosting services don’t provide ssh access, hence the convoluted steps with yafc etc.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s