Working with WordPress & GIT

Avoid cowboy coding techniques and learn how to keep your WordPress website project in GIT version control.

Working with WordPress & GIT

Every developer has their own way of dealing with the beast that is WordPress whilst trying to follow good development practices. It's always best to avoid 'Cowboy Coding'; aka hacking code on the live server. With the ability to edit theme & plugin files through the admin area, WordPress makes this bad practice far too easy. Then you have auto-updates and content editors installing 3rd party themes and plugins. This quickly leads to development versions becoming out of sync with the live website and therefore problems are likely when it's time to deploy your latest changes.

The solution is keeping the project under version control with GIT. However, keeping your WordPress site in GIT can be tricky; there are lots of different ways of handling it - should you commit the WordPress core? What happens when a new version is released? What about 3rd party plugins? You need a sensible process to follow.

Read on to discover my process for setting up a new WordPress website project in version control using GIT (I assume you comfortable with GIT & and using the command line).

Create the repository

I start off by creating a directory for the project, adding an empty README file then making the first commit to the repository.

mkdir www.myproject.com && cd www.myproject.com
git init
touch README.md
git add README.md
git commit -m "Inital commit of files."

Get the WordPress core

Next up it's time to get a copy of the WordPress core by adding a GIT submodule. At the time of writing, the current version of WordPress is 3.9; you may need to change the git checkout 3.9 command this to get the version you want to be running.

git submodule add git://github.com/WordPress/WordPress.git wordpress
git commit -m "Added WordPress submodule."
cd wordpress
git checkout 3.9
cd ../
git commit -am "Checked out the latest WordPress version."

Copy editable & important files

By default, WordPress keeps all of the files you need to edit within a sub-directory of itself - which causes problems now it's setup as a submodule. I copy the wp-config-sample.php file and the wp-content directory from the WordPress directory up a level into the project level directory where they're safe to edit. I also need to copy the index.php file that handles pages requests to the top level project folder as well.

cp wordpress/index.php index.php
cp wordpress/wp-config-sample.php wp-config.php
cp wordpress/wp-content/ wp-content/
git add .
git commit -m "Copied editable and important WordPress files out from the WordPress directory."

Making the index.php and wp-config.php files work outside of WordPress directory

I now update index.php so it knows where to find the rest of the WordPress installation - I need to change this line:

require( dirname( __FILE__ ) . '/wp-blog-header.php' );

to

require( dirname( __FILE__ ) . '/wordpress/wp-blog-header.php' );

I then need update the wp-config.php file with my database credentials for both my local development and production environments (replacing the existing definitions). I also need to define some URLs and paths because I have moved the files around.

/**
 * Define paths and URL's
 */
define('WP_SITEURL', 'http://' . $_SERVER['SERVER_NAME'] . '/wordpress');
define('WP_HOME', 'http://' . $_SERVER['SERVER_NAME']);
define('WP_CONTENT_DIR', $_SERVER['DOCUMENT_ROOT'] . '/wp-content');
define('WP_CONTENT_URL', 'http://' . $_SERVER['SERVER_NAME'] . '/wp-content');
/**

Environment: Dev
*/
if( $_SERVER['HTTP_HOST']=='www.myproject.dev' ) {
define('DB_NAME', 'database_name');
define('DB_USER', 'database_user');
define('DB_PASSWORD', 'database_password');
define('DB_HOST', 'database_host');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
}

/**

Environment: Live
*/
else {
define('DB_NAME', 'database_name');
define('DB_USER', 'database_user');
define('DB_PASSWORD', 'database_password');
define('DB_HOST', 'database_host');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
}

Finally, I need to add and commit these changes to the repository.

git add .

Configure .gitignore rules

I choose not to keep un-necessary files in the repository, so I now setup a .gitignore file. Below are some WordPress specific rules I usually add to my starter template, however it varies project to project about exactly what is in there.

# Ignore uploads directory
wordpress/wp-content/uploads/*
Ignore upgrade directory
wordpress/wp-content/upgrade/*
Ignore plugins (personal preference if you want to use this or not, I add excludes if there is a specific plugin I do want to include in the repository)

Ready to code!

That's it - I'm now setup with an easy-to-maintain GIT repository for my WordPress project. I can now install WordPress and start working on my custom theme.

I hope you find this useful - feel free to get in contact if you have any questions or suggestions for improvements - I'm @gbuckingham89 on Twitter.