How can I automate checkout on click?

Consider the following situation:

I have a git repository foo.git that contains the javascript project code. This repository has a branch production that contains the state of the code served by the web server that pulls the code from /var/www/foo

. This repository is the main repository for the project. Everyone pushes and pulls from / to him.

Is it possible to upgrade /var/www/foo

to a production checkout when someone pushes to that particular branch? You can assume that the git daemon (or the git user, which is the user that all people register to connect to over SSH) has write permission to the specified directory.

+3


source to share


3 answers


You need to create a bare repository on the server with git init --bare

. Then use the post-receive

hook to start the deployment. How you deploy is up to you.

My deployment strategy

I usually put a directory deploy

somewhere logical. Then each checkout I unpack the last branch to deploy/COMMIT_ID

, where COMMIT_ID

is the hash of the last push. Once validation is complete, you can reassign the symbolic link to the latest deployment directory.

My usual directory structure:

deploy.git/
deploy/
    a7922231/
    b2f0a2af/
    latest -> b2f0a2af 

      

Unpacking the update

Instead of using, 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 webserver may be pointing to deploy/latest

, updates will be more or less atomic.

I use this a lot during production and have several advantages over unpacking over the same directory.

  • kickbacks are simple.
  • you can perform post-decompression procedures such as compiling or installing dependencies without interrupting your current deployment.

Tips

  • each update is appended to the deployment log , which indicates when the updates happened and what their hash IDs are. This makes rollbacks a lot easier.
+2


source


You need to create a file post-receive

in yours /git/foo.git/hooks directory

(based on my comment above). Something like this (with some debug protocol):

#!/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 need to set up a git repository /var/www/foo

to track the production branch of another repository. If it is called a source, then it is:

git branch --set-upstream production origin/production

      



And of course the production department should be checked out in your repository /var/www/foo

.

UPDATED

Maybe a hook is post-update

more appropriate (sample from here fooobar.com/questions/1994383 / ... ):

#!/bin/bash    

case " $* " in
*' refs/heads/production '*)
    cd /var/www/foo
    git --git-dir=/var/www/foo/.git pull
    ;;
esac

      

+1


source


You can check out the git repository foo.git

into a directory dir

with the following commands:

git archive | tar x dir

      

0


source







All Articles