ExpressionEngine, Tutorials

Version Control for ExpressionEngine Using Git (Part 1)

August 24, 2009
by Ryan Masuga

ExpressionEngine and version control has always been a topic of interest to EE developers, but versioning an EE site can be tricky. This series of articles covers the basics of getting an EE site up and running under the Git version control system. In Part 1 I cover installing Git and setting up a local environment.

Git and ExpressionEngine

Thoughts and Assumptions

Version control is something I felt I needed a handle on when developing with ExpressionEngine, so I recently starting looking for a solution I could use in my own workflow. Up until very recently, I’ve been working on projects myself (except for the occasional contractor who has helped migrate or enter content into EE while I’ve been working on the template side) but now I’m finding the need to do some collaborative work, and also want to make sure that my work is properly backed up and versioned—so I can roll back changes if something goes awry.

Version control can be critical when numerous collaborators are working on different parts of a site (particularly templates that are saved as files) and who might also be working on the same areas at the same time. Entry and template revisions through the ExpressionEngine control panel are really a different story, and in no way should be confused with a more robust version control system for your templates and files.

The version control system I chose to work with is Git, which many EE developers are using these days. There are now numerous ExpressionEngine add-ons stored in public repositories at GitHub, and you can certainly store whole EE sites there (in private repositories), like I do. I find Git easy to set up, easy to use, and it does exactly what I need it to do as far as versioning my files and saving my behind when I completely mess up a file. Unlike SVN/Subversion, which litters your directories with “.svn” folders, Git is clean, placing only a single hidden “.git” directory at the root level of your repository.

You will need to feel comfortable using the terminal application, because you’ll be spending some time there, so if you’re the type of person who absolutely needs a GUI, Git may feel a little too geeky for you. One way to get some GUI goodness into your Git workflow is to download GitX. GitX is a useful app for viewing the differences in commits on a local repository, among other things.

Devot:ee in GitXViewing recent commits for devot:ee in GitX. This is as GUI as Git gets.

This is a detailed subject and will be addressed in multiple parts. What I cover in this series is by no means a be-all end-all way to do things; I’m just documenting what I do and what I use for my workflow. Take as much as you need, and leave anything behind you don’t want to utilize. The first couple parts won’t be very EE-specific, but by the time you get to the EE stuff, you might be glad the first two parts are here for a little background.

Software & Hardware

For the sake of argument, I’ll assume you’re using:

EE Practice: Saving Templates as Files

I’m assuming you’re saving your EE templates as files, and that you’re working on a single non-MSM EE site. I don’t know how working on a Multi-Site Managed site would be any different, but I don’t have any experience doing so, so it’s beyond the scope of this series.

Saving Templates as Files in ExpressionEngine

If you’ve never saved templates as files before, there is a radio-button setting in your control panel under Templates > Template Preferences titled “Allow Templates to be Saved as Files?” Set that to “Yes”. The next setting is “Basepath to Template File Directory” where you are to supply the server path to the folder that will contain your template files. That might read something like /home/yoursite/public_html/my_template_files. This will vary depending on your server.

In Part III of this series, when I get to very EE-specific things, I’ll cover how to override this setting with a variable in the config.php file located in your system folder, so that the value here in the control panel will ultimately be ignored. For now, set this to the correct path. There is no need to set the “Save Template Revisions” setting to “Yes” if you’re going to be using a version control system to manage the changes. This will also keep your database lighter, and give ExpressionEngine one less thing to do or worry about.

Template as File Checkbox

Saving a template as a file is now as easy as clicking on a template’s name in the Templates tab, checking the “Save Template as File” checkbox, and finally clicking “Update and Finished”. If the path to your templates folder is correct, and the permissions on it are correct, you should see your template group there as a folder, and your template should be inside. Ideally, you never have to come back to this template through the Control Panel ever again. I never touch templates in the EE Control Panel after having created them and saved them as a physical file, unless I need to alter settings on it, like enabling PHP for it or setting caching. The full instructions for saving your templates as text files can be found in the EE online docs, under Templating System.

I personally think saving and editing templates as files should be the default way things are done. Who edits markup and code on complex templates, on complex sites, one at a time, essentially on the live server, in a browser textarea with no code coloring or advanced text editing options? If that’s you, you’re are insane!. I go into some real examples of Git and EE in action in Part IV of this series.

GitHub and SSH

I’ll assume you have an account at GitHub, although this is not required. I’ll also assume the company hosting the website you’re working on allows you shell access—and this is a pretty big deal. All of this may be pointless if you don’t have shell access to your account. If you can’t SSH into your account, you’ll probably have to find another way to do version control. You may be able to do this without shell access, but I don’t deal with hosts that don’t allow it, so I’ve never had to look into the matter. Also, having remote mySQL access is a major bonus, although not entirely necessary (remember, EE is a very database oriented CMS), but more about that in Part III when I get to EE specifics.

Other Resources for ExpressionEngine and Git

There is a series of parallel articles currently being published by Stephen Lewis over at Experience Internet. At the time of this writing, there are three existing articles:

Some of my information will overlap Stephen’s information, but my hope is that all of these Git articles will highlight different areas and ultimately complement one another.

Also see the ‘Using git to Manage an ExpressionEngine website’ EE forum thread that Stephen started for further discussion and information on using Git and EE together.

One Step Further for Deployment: Capistrano

Dan Benjamin has written an article titled Deploying ExpressionEngine from GitHub with Capistrano, some of which may be helpful to you in understanding what I’m talking about here. However, he goes into detail about using Capistrano to deploy your EE site, which this series of articles will not touch on.

For those interested in even more information on deploying EE with Capistrano, George Ornbo of Shape Shed has also posted on this subject: Deploying ExpressionEngine with Git and Capistrano

OK, all that is out of the way and in the books, so let’s get started setting up your local environment.

Installing Git

There really isn’t much to it, and this may be the easiest part of the whole series.

Local Install

The simplest thing to do is to use the Git OSX installer at Google Code. This is what I did, although there are other options. You can use MacPorts or as outlined at GitHub, you can compile and install Git yourself.

For those of you using Snow Leopard who would like to compile Git on your machine, Hivelogic has recently published an article on just that: Compiling Git on Snow Leopard.

Remote Install

Hopefully, you’re on a host that already has Git installed. You can easily find out when you SSH in to your remote server and just type “git” at the prompt. If git is installed, you’ll get a list of common commands. If it’s not installed, you’ll likely get “command not found”.

If you’re on a VPS or a (managed) dedicated server, you can probably just request the hosting company install it for you, and if they’re any good, they’ll have that done very quickly (shoutout to Liquid Web (affiliate link) – they’re a great host with awesome support, shell access, Git, and did I mention great support?). I would recommend you let the host take care of installing Git, if possible.

You can install Git yourself with Joe Maller’s instructions titled “How to install Git on a shared host” which also works if your site is on a shared host, which is great…considering that’s the title.

Installing Git in a Shared Hosting Environment

A shared hosting environment is not ideal (on so many levels). Most shared accounts are on boxes that don’t allow remote mySQL connections, which can be a major pain when working with EE under version control, unless you have some sort of automated system in place to copy the remote DB to your local machine and sync all your changes when you’re done – which is something I may touch on in Part III when I get into EE specifics and EE workflow.

You can install Git on a shared hosting account if you need to, and I’ve successfully gotten it to work using Joe Maller’s instructions. In one particular case I also had to make use of the last line from this Git article, where you update the .bashrc file so that the shell could find git. You may not have to do that depending on the server you’re on.

Assuming you have git installed both locally and on the remote server, let’s make life in the Terminal a little easier.

Tweaking the Terminal

Change the bash prompt

This part is totally optional, but one of the things to note about Git is that, on the Mac, you’re going to spend a lot of time in Terminal. As of this writing I’m not aware of any GUIs for Git (other than GitX, mentioned above), so Terminal is it. Although the Terminal and command line can appear daunting and scary, for what you’ll be doing with Git it’s really not that bad as long as you know what you’re looking at.

The first thing I did was download and install the IR_Black terminal theme to give my terminal windows a nice light on dark base.

The next thing I wanted to do was change the color of my prompt so I could distinguish it from the commands I was typing. There is info all over the web about this, but none of it is right to the point, and most of it is downright confusing. The best article I found was Ian Beck’s “A better bash prompt on Mac OS X”. There is also some very clear info at IBM in an article called Prompt Magic: Enhancing the system prompt. These articles will help explain different variables and color codes.

In my .bash_profile file (in the root of my user directory) I’ve added this line:

PS1="\[\e[01;31m\]\w \$ \[\e[00m\]"

That gives me a red prompt with very simple, minimal information. If I were in my local devot-ee directory, I would see:

~/Sites/devot-ee $ The prompt is red, this text is not.

If you want to take it a step further, you can show your current Git branch in the prompt. Again in .bash_profile, use the following instead:

parse_git_branch() {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'

PS1="\[\e[01;31m\]\w \$(parse_git_branch): \[\e[00m\]"

Now, on my local machine, I’m seeing this as my prompt, (assuming I’m in the devot-ee directory, that the directory is managed with Git, and I’m on the master branch):

~/Sites/devot-ee (master): We’re on the master branch

This is very handy once you start using Git branches (which may be touched on in Part VI, where I share real experiences developing with Git/EE). There full explanation for adding Git branches to your shell prompt can be found in the Git Guides at GitHub.

On remote machines, if I log into shell, I like it to be a little more descriptive, because I can easily lose track of which box I’ve SSH’ed into. Again, I like the red color:

PS1="\[\e[01;31m\]\u@\H:\w \$ \[\e[00m\]"

Logging into the live devot:ee server would then show me a more detailed prompt: $ cd public_html/

Set Textmate as Git’s Text Editor

If you’re a layman like myself and terrified of actually editing text in a text editor that runs in the terminal like vim (insert and command modes, what?) then it’s easy to set Textmate as Git’s editor. Just open Terminal and type the following:

~ : git config −−global core.editor "mate -w"

You may also want to set up Textmate and Terminal to talk to one another. Textmate has a Terminal plugin you can install so that all you will have to do to jump from where you are in Terminal is to type “mate” and Textmate will come up. View the Textmate Manual for more information on Textmate and Terminal. As an example, say you move to your “monkey” project in your Sites folder:

~ : cd Sites/monkey
~/Sites/monkey (master): mate .

That would open every file in the ‘monkey’ directory in a project view, which is pretty convenient (note the period at the end to signify “all”).

Terminal mate command“mate” command in Terminal to open file(s) in TextMate

Global Git Shortcuts, and Colors!

Setting up Git shortcuts can save you many, many keystrokes. For example, I find it much easier to type “git st” to get the current status of my Git project than “git status”. Same goes for “git commit” and git “checkout”. For me, 2-letter codes are the way to go.

It’s very easy to set up these shortcuts. You can set them up globally on your local machine, and also add them to the remote repos if you’re accessing those directly.

If you’re using TextMate, from your root directory just type:

~ : mate .gitconfig

You should probably see the core.editor config value we just added, and there may be a few other things in the file already. This is the global .gitconfig file. If you need to, you can override these global values on a repo by repo basis by editing the “config” file within the “.git” folder in your repository. My global .gitconfig file looks like this:

  email =
  name = Ryan Masuga
  branch = auto
  diff = auto
  status = auto
[color "branch"]
  current = yellow reverse
  local = yellow
  remote = green
[color "diff"]
  meta = yellow bold
  frag = magenta bold
  old = red bold
  new = green bold
[color "status"]
  added = yellow
  changed = green
  untracked = cyan
  st = status
  ci = commit
  co = checkout
  br = branch
  whitespace = nowarn
  editor = mate -w

If you’re feeling adventurous, you can just copy and paste the above, changing only the “user” info. This should set up colors for you similar to those in the background of the opening image of this article: green for modified files, yellow for files to be committed, etc. You can now use the shortcuts as well.

Below is a simple example of doing a “git (st)atus” to view the current state of my project, and then “git (br)anch” to see the available local branches that I’m working on. This shows you how the colors may appear in your terminal that will help you easily distinguish between files in different states when working with Git.

~/Sites/devot-ee (master): git st
# On branch master
# Changed but not updated:
#  (use “git add <file>…” to update what will be committed)
#  (use “git checkout — <file>…” to discard changes in working directory)
#    modified: tpl/members/edit.php
#    modified: tpl/submit/add-on.php
# Untracked files:
#  (use “git add …” to include in what will be committed)
#    tpl/articles/my_new_file.php
no changes added to commit (use “git add” and/or “git commit -a”)
~/Sites/devot-ee (master): git br
~/Sites/devot-ee (master):

You’re now Git to Go®, so I’ll leave you here, while I prepare to take you somewhere with all this…

In the Next Installment

In Part II, we’ll put a local site under Git version control and look at the basics of committing, pushing and pulling before getting into very EE-specific things in Part III.

Do you have comments or thoughts? Ideas to do something better? Was anything unclear? We’d love to hear about it in the comments.


JayF 08.24.09


This is a great topic to be covering. I tried to bring Git into our EE process last month, and felt like it wasn’t working for us. So, I am looking forward to your articles to get your perspective on it—see what I missed so I can give it another go sometime.

George Ornbo 08.25.09

George Ornbo

It might be worth noting that the original developer of the Capistrano project has given it up and that it has been taken up by someone else. For the short term, if you do have any issues use the 2.5.5 release. There’s a page+ on the documentation site explaining issues that have arisen since the new author has taken it on.

It might also be worth noting that you don’t just have to use Capistrano with Git – it works just as well with Subversion, although if you are using SVN over Git I feel sorry for you.

elemental media 08.25.09

elemental media

Thanks Ryan, I have been following your steps and seems like the EE typography formatting got in the way:

~ : git config —global core.editor “mate -w”

The m-dash should be 2 dashes and the double quotes are turnd into typographical quotes. So it will not work in the terminal and can confuse those who copy/paste directly.

~ : git config --global core.editor "mate -w" 

Ryan Masuga 08.25.09

Ryan Masuga

@elemental: Thanks for pointing that out. I think I’ve fixed it with some encoding.

Tyssen 08.28.09


Sitepoint has also just published a beginners’ guide to using Git which might prove useful for other Git newbies (like me).

Matt Weinberg 08.29.09

Matt Weinberg

These are great tips. I especially loved the advice about customizing terminal— should make it a lot easier when constantly going back and forth between different servers with SSH.

Toby Sommer 08.31.09

Toby Sommer

Ryan, thanks for covering this! A really good start into Git is the Pro Git Book (completely online). I hope, Part 2 is coming a.s.a.p :)

CreativeSoapbox 09.04.09


I finally got my cursor to stay red. I realized I didn’t have a .bash_profile in my home folder. Here’s how, in terminal in your home directory:

#Check to see if you have one
ls -a

# if not, create a blank file and open it
touch .bash_profile
open -e .bash_profile

# this will open it in TextEdit (or whatever is your default) 
# add this to the file (notice the addition of export)
export PS1="\[\e[01;31m\]\w \$ \[\e[00m\]"

#save and exit TextEdit

I had to quit terminal and start it up again to get the changes to show.

Jim Pannell 09.11.09

Jim Pannell

Fantastic article Ryan – it’s making my transition from Subversion a lot easier. I just need part 2 now for my life to be complete ;-).

Any idea of the eta?

Pascal Kriete 09.17.09

Pascal Kriete

If you installed git text completion, you can also get the current branch through the __git_ps1 function:

export PS1="\h:\w\$(__git_ps1 \" &#123;%s&#125;\")\$"

Where %s will be replaced with the current branch (in this case wrapped in {}).

Damien Huze 10.06.09

Damien Huze

Great stuff Ryan, thanks for the putting in the time to write the article.  Hope you’ll get the courage to write Part 2 soon!

You must be registered member to comment. If you're already a member, log in now, and if not go register (it's free and easy!).