in Blog

Trying out the “Push to deploy” feature of Git 2.3

Git 2.3 was recently released with an interesting new feature called “Push to deploy”. It allows a non-bare repository on a remote server be automatically updated. This was previously only possible with bare repositories, updating the current branch in non-bare repositories was denied by default.

A common scenario would be a web application that gets automatically updated when a developer pushes commits on the production branch to the repository on the web server. Of course there are a variety of other scenarios where this would come in handy, and also plenty of risks.

Still, I wanted to try out, here are my notes. I used meaningful names for the directory to “simulate” the scenario described above (local -> webserver). All commands assume are operating from a home folder.

Create git repository

We are creating our “local” repository and create an initial commit.

$ mkdir ~/local
$ cd ~/local
$ git init
$ touch file && git add file && git commit -am "a file"

Clone repository on webserver

Now we’re cloning the repository to the “webserver”.

$ git clone ~/local ~/webserver

At this point, the two repositories have the same commit graph, namely the one commit “a file” we created in the first part.

Adding the webserver as a remote

$ cd ~/local
$ git remote add server ~/webserver

Deploy to the webserver?

Let’s see how this works without the new feature.

$ cd ~/local
$ touch file2 && git add file2 && git commit -am "file2"
$ git push server master

Whoops, this doesn’t work. The following warning appears:

remote: error: refusing to update checked out branch: refs/heads/master
By default, updating the current branch in a non-bare repository is denied, because it will make the index and work tree inconsistent with what you pushed, and will require ‘git reset –hard’ to match the work tree to HEAD.

You can set ‘receive.denyCurrentBranch’ configuration variable to ‘ignore’ or ‘warn’ in the remote repository to allow pushing into its current branch; however, this is not recommended unless you arranged to update its work tree to match what you pushed in some other way.

To squelch this message and still keep the default behaviour, set ‘receive.denyCurrentBranch’ configuration variable to ‘refuse’.

Set-up “Push to deploy”

For this to work, we’re now setting up “Push to deploy” on the webserver.

$ cd ~/webserver
$ git config receive.denyCurrentBranch updateInstead

Push to deploy!

$ cd ~/local
$ git push server master
4d5947f..d71e13e master -> master

And the webserver repository is updated!