So far I used Subversion as version control system and my usual workflow is quite simple:
IDE => Subversion repository => live web application
I develop on my local machine, commit the code to the Subversion repository on the server, and finally export the code from the repository to the live application. That works fine.
However, as I wasn’t able to connect to Subversion repositories from Netbeans (the IDE I currently use for Ruby-based stuff) for whatever reasons, I had to look for a different solution. I could learn to use Subversion from the command line, or I could use this opportunity to dive a bit more into Git. And as you can guess from the subject of this article, I have chosen the second option: Git.
After learning the basics, I looked around to see how others use Git and I found a web-focused Git workflow by Joe Maller, which I used as a basis for my own workflow. The workflow is:
IDE => local Git repository => remote bare Git repository => Git repository with the live web application
As you can see, it’s a bit more complex than the previous workflow, as it involves three repositories instead of one.
I still develop on the local machine, however, now I commit to a local Git repository. From this local repository I push my changes to the remote bare Git repository (“bare” meaning the repository doesn’t have a working directory). This repository then “notifies” the Git repository with the live application about the changes, so that this repository can pull the changes from the bare Git repository (technically, this is incorrect, as you will see later).
Ok, now let’s have a look at how such a workflow is set up.
The first step is to set up the local repository:
$ mkdir -p projects/example $ cd projects/example $ git init // create some files $ git add . $ git commit -m "Initial commit"
For the next step we have to switch to the server, and set up the bare repository:
$ mkdir -p git/example.git $ cd git/example.git $ git --bare init
To be able to push data to this bare repository, we have to tell our local repository about this remote repository. We do this with the following command (on the local machine):
$ git remote add exampleserver ssh://firstname.lastname@example.org/~/git/example.git
If everything went well, we can now push the data to the server with the following command:
$ git push exampleserver master
Tip: if you want to avoid typing the SSH password every time you push data, create a public/private key set as described by Casper Fabricius.
The next step is to create the repository which will contain the live application. For this purpose we switch again to the server. This time, we create a “normal” Git repository, because the working directory will contain the application. As this repository will pull the data from the bare repository, we have to add that bare repository as a “remote” repository.
$ cd ~ $ mkdir example.org $ cd example.org $ git init $ git remote add bare ~/git/example.git
Note: make sure your document root doesn’t point to “example.org” but to a subdirectory!
The final step is to define the “post-update” hook script on the bare repository, which is called when the bare repository receives data. To enable the “post-update” hook, we have to either make hooks/post-update executable or rename hooks/post-update.sample to hooks/post-update, depending on the Git version. In this script, we simply change to the folder of the live application, and start the pull operation:
#!/bin/sh cd $HOME/example.org unset GIT_DIR git pull bare master exec git-update-server-info
Now, with everything set up, we can deploy the application from the local machine with a single command:
$ git push exampleserver master
I hope I could give you an overview of how a Git workflow for a single developer could look like. Feedback is welcome!