Skip to main content
Marc Jenkins

A WordPress & Git workflow

I’ve been using WordPress and Git together for several years. I started out by storing everything in Git. This meant that the repo contained server configuration files which required awkward workarounds, such as using a switch statement in wp-config.php and creating a fancy .htaccess file. Updating WordPress was also a pain.

A couple of months back, I switched to a new way of thinking: keep the repository as empty as possible. Anything that doesn’t need to be in there, shouldn’t be in there. That means WordPress core files, uploads and plugins. Essentially, we’re now just storing the theme.

To do this, we use the following .gitignore:

This now caused another problem. When a team member cloned a repository, they’d need to manually setup WordPress before the site would work. As there is no wp-config.php, or any WP core files, it was a case of manually copying the files over. The same problem occurred when deploying repositories to new servers.

To get around this issue, I’ve started using WP-Cli which is a set of command-line tools for managing WordPress installations.

So, lets say we have a repository with a theme in it. To get this working locally, we could do something like this:

git clone repo-url my-site/
cd my-site/
wp core download
wp core config --dbname=mysite --dbuser=root --dbpass=password --dbhost=127.0.0.1

The commands above are simple. We’re cloning the repository and then moving into that directory. Next, we’re using WP-Cli to download the WordPress core files and create a wp-config.php file with the database connection details. If WordPress is already installed, we’re good to go. If it isn’t installed, you’ll need one more command:

wp core install --url='http://localhost/my-site' --title='My Site' --admin_user=admin --admin_password=password --admin_email='[email protected]'

And bosh, we’re up and running.

Want to install and older version of WordPress? Just include the --version parameter.

wp core download --version=3.8

Need to upgrade WordPress? No problem:

wp core update

Installing plugins is a piece of cake, too:

wp plugin install advanced-custom-fields --activate

wordpress.txt

Using WP-Cli works great if you have all the database connection details to hand. You’ll also need a list of plugins to install. This was particularly a problem with my team. We get around this problem by creating a file called wordpress.txt in the template directory. It contains local database connection details, any plugins that are used, and anything else that might be required that isn’t part of the repository. That way, it’s easy for a someone new coming to the project to know what’s involved and how to get up and running. A typical wordpress.txt file might look like this:

=== WP Version ===
WordPress 3.9.1

=== DB Connection Details ===
wp core config --dbname=mysite_dev --dbuser=root --dbpass=password --dbhost=127.0.0.1

=== Plugins ===
advanced-custom-fields
akismet
wordpress-seo
wp-migrate-db-pro

Branching

Typically, I have 2 branches on a project: staging and production.

I work locally on the staging branch. Staging, as you’ve probably guessed, deploys to the staging server and production deploys to the live site. If I’m working on a big feature, I’ll create a new branch. That way I am free to continue working on the site while the new feature is being developed.

Tools

I use the following tools:

Beanstalk

For hosting repositories and making deployment easy

iTerm2

Terminal, for Git and WP-Cli

I use the built in Mac OS X webserver. Luke Jones has a great guide on how to set this up.

Syncing databases

The one thing that was missing from my workflow was moving databases. Up until recently, I’d have to export the database as an .sql file, do a search and replace for various paths, and then reimport.

I’ve since started using WP Migrate Pro. It’s bloody good and if you regularly find yourself moving WordPress databases, you should go buy it now.

It allows you to ‘pull’ or ‘push’ databases. So, for example, if our local dev environment is out-of-date, we can simply click “pull from staging”. A minute later, everything has synced across. It’ll make a backup of the database in the process and can move the uploads folder if required, too.

Future improvements

I’m always tweaking and improving my process. I’m a big fan of SASS and currently store the compiled CSS in Git. When my team are also working with SASS and pushing compiled CSS files, it can cause conflicts. I’ll be looking into some build scripts to see if it helps resolve this problem.

I hope you found this useful. I would love to hear your suggestions and improvements, or even your own workflow!