Consider the following situation:
I have a git repository foo.git that contains code of a javascript project. In this repository there is a branch production that contains the state of the code as served by a web-server which fetches the code from /var/www/foo. This repository is the master repository for the project. Everybody pushes and pulls from/to it.
Is it possible to have /var/www/foo updated to a checkout of production whenever someobody pushes to that particular branch? You may assume that the git daemon (or the user git which is the user all people log in to to connect via SSH) is entitled to write to said directory.
You have to create a bare repository on the server with git init --bare.
Then use a post-receive hook to trigger your deploy.
How you deploy is up to you.
I usually place a deploy director, somewhere logical.
Then each checkout, I unpack the latest branch to deploy/COMMIT_ID where COMMIT_ID is the hash of the latest push. Once the checkout is complete, you can re-point a symlink to the latest deployment directory.
My usual directory structure:
deploy.git/
deploy/
a7922231/
b2f0a2af/
latest -> b2f0a2af
Rather than use a git-checkout, I usually use git-archive to unpack a branch into a directory.
# Assuming current directory is deploy.git
HEAD=`cat refs/heads/master`
mkdir -p ../deploy/${HEAD}
git archive master | tar -x -C ../deploy/${HEAD}
Your web-server can point to deploy/latest, updates will be more-or-less atomic.
I use this often in production, and has a few benefits over unpacking over the same directory.
You have to create a file called post-receive in your /git/foo.git/hooks directory (based on my comment above). Something like this (with some debug log):
#!/bin/sh
echo 'Hook called'
pullneeded=false
while read oldrev newrev refname
do
echo "OLDREV $oldrev NEWREV $newrev REFNAME $refname"
if [ "$refname" == "refs/heads/production" ]; then
echo 'Pull needed'
pullneeded=true
fi
done
if [ $pullneeded ]; then
echo 'Pull'
cd /var/www/foo
git --git-dir=/var/www/foo/.git pull
fi
echo 'Hook done'
You have to set up your git repository at /var/www/foo to track the production branch of your other repository. If it's called origin there then it is:
git branch --set-upstream production origin/production
And of course the production branch has to be checked out in your /var/www/foo repository.
UPDATED
Maybe a post-update hook is more appropriate (sample is from here https://stackoverflow.com/a/6597728/299788):
#!/bin/bash
case " $* " in
*' refs/heads/production '*)
cd /var/www/foo
git --git-dir=/var/www/foo/.git pull
;;
esac
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With