The idea behind is to push to a remote repository on the same web/service server and a post-receive hook will checkout the files to the public directory.

Configuring the server

Create the repository:

$ cd $HOME
$ mkdir my-site.git
$ cd my-site.git
$ git init --bare

The idea of using .git as a suffix is just to distinguish between other directories.

Crate the directory where you would like to deploy, for example:

$ mkdir /home/sites/my-site

Create a post-receive hook

When you create a bare repo, normally you get this structure:

 my-site.git
├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── fsmonitor-watchman.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags

The post-receive hook (located within the hooks directory) will be called after git has received commits, for example create the file $HOME/my-site.git/hooks/post-receive with this contents:

#!/bin/sh
git --work-tree=/home/sites/my-site checkout -f

Set exec permissions to the hook:

chmod +x hooks/post-receive

Configure your local machine

Once you have setup your remote repository and the post-receive hook, you could add a second origin, something like:

$ git remote add live ssh://[email protected]/~/my-site.git

Normally your project already has a remote named “origin” in where you can continue pushing your changes, branches etc; this new remote named live will be only used to checkout/publish your changes after receiving a commit.

Deploy

Just need to push to your remote named live in this example:

$ git push live master

After doing this, you could check your remote server and check the contents of /home/sites/my-site it should be updated to your latest changes.