<<< Back to the blog

Git workflow

it me
Published on
Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.

A look at how I'm working with Git.

There are a ton of Git workflow articles out there by various developers, this is how I roll.

I use Git for all development work, the majority of that is ExpressionEngine based but I've also been using it with for front-end development work, my explorations with Django and even for design work in Photoshop (although way harder to track real changes).

Much of our work is in ExpressionEngine so that will be the premise for this post .

It used to be that setting up an ExpressionEngine site took a lot of time. With each site I developed, I realised that there were common components and characteristics on just about every site (there are always exceptions to the rule).

ExpressionEngine setup

I set about creating a base ExpressionEngine installation. So on my Mac, I have a site running on Apache called - my default ExpressionEngine install consists of:

I have 1 channel & 1 default field group (Page with custom fields {cf_page_summary}, {cf_page_content}) and 2 template groups (embeds and layouts).

Embeds contains and html head template and layouts contains a home template and page template. Both of these templates include the html head and also 2 snippets {sn_mast} & {sn_footer} (Snippets are in the file system too for VC).

My page template has a channel entries call and uses the custom fields for the page.

Above the webroot, I also have a db folder containing an sql extract of my install.

I also use our own bootstrapped config file ( and database file too (

So with that setup, I initialised our Git repo, added everything on the site and committed it.

I have have a VPS that runs Gitlab ( to store all of our Git projects. Gitlab is similar to Beanstalk, CodebaseHQ  etc but I can have as many projects, users, repositories as I want (I like to store all of my work and to do that on a subscription service would be costly). Gitlab also has an issues tracker as well that I can give clients access to during development of a project and those issues can be assigned to specific developers if needed. I can also restrict the access on projects so that users can: administer a project, read issues only, read/report, pull only, push/pull.

In Gitlab I have an EECMS project that only 1 Git master (for the moment) has access to. That Gitlab project is the master for the local install so I add that remote master to my local repo git remote add origin [email protected]:eecms.git

If I tinker with that local install at all (someone releases a new awesomesauce add-on that needs to be part of our base install) then I’ll install on my local repo, dump the db sql again to db above webroot, add my files, commit the changes and then `git push origin master`

A new project

So how does this work when there’s a new bit of work? Well, I’ll create new folder on my Mac, clone from Gitlab git clone [email protected]:eecms.git . and then create my virtualhost in Apache, create my new db and execute the sql file.

Then it’s a case of updating my config.php for my development environment to use my new db settings. It’s at this point I start using Tower ( although I do still have Terminal open as well. It’s imperative at this point to DELETE THE REMOTE MASTER. If you don’t you risk pushing changes from this new project into your master. I’ve been there and it’s not fun, especially if other folk are pulling from that master. It can cause headaches.

I’ll then setup a new project in Gitlab and then set my new remote for that project on my local install.

From there, I develop, I test, I add, I commit. The key for me is committing often. So for example, I’m working on the CSS for a specific page element. I’ll commit when those styles are give a good basis for the style of that element. Same with EE templates, develop the template a little, commit with Git. Develop some more, commit with Git.


Here’s the scenario, site build is going great, client calls and says “we need to have part X interacting with a new part Y” - part X already works great so you don’t want to screw that so I create a new branch `git branch part-y` and then switch to that branch git checkout part-y. I can then work on that branch, test and commit as on the other branch. It looks great and functions as expected, I can move that back into the master branch.

git checkout master git merge part-y


Hopefully…it should merge your changes in part-y with your master branch. Depending on your changes, you may have some conflicts, simply fix the conflict (in the scenario below Goodbye is the new change I want to keep) and commit the change.

  <<<<<<< HEAD:file.txt
  Hello world
  >>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt


We haven’t settled on a deployment strategy yet. I have used a few variations so far that include:

  • cloning the Gitlab repo into the test or live server (when I make changes in the local repo, I push those to Gitlab, ssh into the test/live server and then do a git pull)
  • using DeployHQ ( - connect your repo to your DeployHQ account, setup your servers in Deploy and then run a deployment
  • Capistrano alternative - can’t remember it’s name
  • Capistrano - I just couldn’t get it to work for me and I gave up

DeployHQ is nice, especially if you’re using the CodebaseHQ system too - however, paying for another subscription service when I can ssh into a server and pull seems a bit redundant. DeployHQ does have a free account (1 project allowance) and allows number of free deployments per day. If you’re only using this for deploying to production then it should suit you well.


Version controlling databases is hard (unless you’re using MongoDB) - during development the db isn’t too much of an issue. I use Navicat to transfer the db schema between environments. Once a project is live, things become a little bit more difficult, particularly when your client is adding content to the db.

I don’t think there’s any silver bullet yet.

Recommended reading


Leave me a message. If you like what you read here, there's a great chance we could be a good fit. If it's something I don't do, I'll likely know someone who does.