Developing on WordPress using Git

WordPress uses Subversion (SVN) for revision management. Before Subversion, it used CVS. Right now, Git is a hot option in the SCM category. It offers really nice features such as decentralization, speed, fast and cheap local branching, better merging, more offline capabilities, staging of commits, and lots more. It’s premature to talk about moving WordPress core and plugins to another SCM system — we have a lot invested with Subversion and Trac. But be of good cheer. You can have your Git and commit to Subversion too! Here’s how I do it.

First, tools. You’ll need Git, obviously. But you’ll also need git-svn-diff, a Bash script that generates Subversion-compatible diffs.

Download git-svn-diff, put it somewhere in your path, and make it executable. Like this:

curl -L http://rkj.me/a1 > /usr/local/bin/git-svn-diff
sudo chmod +x /usr/local/bin/git-svn-diff

Next, to enable you to do git svn-diff instead of git-svn-diff, edit ~/.gitconfig and add this:

[alias]
	svn-diff = !git-svn-diff

This next step is going to take a while. You’re going to pull down WordPress’ SVN history using Git’s SVN support.

git svn clone -t tags -b branches -T trunk http://core.svn.wordpress.org/

You might want to let that run overnight. Really. It’s going to go through each changeset.

Once you’re done, you should be in the Git master branch, which corresponds to WordPress SVN’s trunk. WordPress’ branches are in remotes/{name}

To pull in the latest changes from SVN, use git svn rebase. Important rule: never modify the SVN branches (remotes/{name}). Instead, create a new topic branch.

For example, say that I’m going to work on a ticket for trunk. I’d create a new branch from remotes/trunk like this:

git checkout -b ticket-12345 remotes/trunk

That will create a new local Git branch called ticket-12345 based on SVN’s trunk, and then check it out (i.e. switch to it).

If you’re working on a WordPress SVN branch, you can do something like this:

git checkout -b ticket-12345 remotes/3.1

Do your work in the branch you created. You can make multiple local Git commits if you want, to break up your work into smaller chunks that make sense to you.

When you’re ready to submit your patch, use git-svn-diff to produce it.

git svn-diff > ~/12345.diff

If you have commit access, you can commit to Subversion from this topic branch. But be careful! First you should do git svn rebase to bring your patch up to date. Next, you should squash your local git commits, otherwise each one of them will be individually committed to SVN (hello, flood). So rebase your commits into one commit, like so:

git rebase -i remotes/trunk

Use “reword” on the first commit. Use “fixup” on the subsequent ones. That will roll the commits up into one. You’ll then be prompted to enter your amended commit message for that commit amalgam.

Ready? You can now commit to SVN using:

git svn dcommit

Git knows which remote SVN branch it came from when you checked out your topic branch. You can verify which one it is attached to by doing:

git svn info

A few tips:

Create a .gitignore file. This lists files or directories that you want Git to ignore. First, you want Git to ignore the .gitignore file itself! Next, you want Git to ignore your local wp-config.php Finally, you want to ignore any additional plugins, must-use plugins, themes, uploads, etc. Just do a git status and add anything that you don’t want to commit to WordPress or put in your patches.

I hope you found this helpful! Let me know if you have any questions.

Just you and your thoughts

In 2007, I wrote this about the job of software:

That’s when I know WordPress is doing its job: when people aren’t even aware they’re using it because they’re so busy using it!

I cited that more as a direction, than a goal. If the job of software is to get out of the way, it never completely reaches it — it just gets closer and closer. Sort of how dividing a number in half an infinite number of times never quite gets you to zero.

Today, in 2011, I took this screenshot of the Distraction-Free Writing interface for the upcoming WordPress 3.2:

screenshot of WordPress Distraction Free Writing interface. A title, and a body.

How’s that for getting out of your way?

WordPress Q & A: Week of September 27

Ricky asks:

Thanks for your time. I’m working on a site where I’d like members to be able to submit posts, but I’d like to be able to moderate them first before they go live.

Kinda similar to what WP can do for comments, I’d like to do for posts. Is that possible?

Certainly! What you want is to open up registration and make the default role for new users “Contributor” instead of “Subscriber.” Contributors can submit posts for review, but not publish them. They’ll show up as “pending review” in the backend, and will require an Editor or Administrator to publish them. There are even plugins available to facilitate posting from the front end, such as Gravity Forms ($39 and up, GPL).

Allan asks:

I have hit an incredibly frustrating hitch with WP, and that is getting a text file with the content of my posts. I need a single file I can load into page layout software. I know about Blog Booker and Blurb but would like more layout control than those services offer.

If you need this for a bunch of posts on an ongoing basis, I’d create a custom page template and just have it do query_posts('posts_per_page=9999'); (or however many posts you want), and then do a basic loop. Look at a simple theme for inspiration on the template tags… it all depends on how you need it formatted.

Import a Vox blog into WordPress (or almost anything else)

Six Apart is closing the doors on Vox, a blogging service they launched three and a half years ago. You have until September 30th to export your content from Vox, or you’ll lose access to it. Yikes!

They helpfully included a link to WordPress.com’s importer help page. WordPress.com has a Vox importer. What isn’t immediately obvious is that you can use WordPress.com as an intermediary on your way to a final destination. That is, you can import your Vox blog to a temporary WordPress.com blog, and then do an export from WordPress.com. Now you’ll have gold: a WordPress export file. You can take this file and import it into a standalone WordPress site, or a plethora of other blogging tools or services.

I recommend that everyone who has Vox content they want to save do this. Mark your WordPress.com blog as private if you don’t want that to be its final destination — just do it (and soon!) so that you have a copy of your site in a useful and portable format.

APC Object Cache Backend for WordPress

I wrote the original APC Object Cache backend for WordPress back in 2006. Shared it via a link on the wp-hackers list, and until a few days ago, hadn’t touched it since.

It has now been updated to version 2.0.1, and should work more efficiently. It supports increment/decrement, and you can now use it to power Batcache, the whole-page caching engine used on WordPress.com! In fact, for single-server sites, it should perform a lot better than Batcache + Memcached (because Memcached is a separate application and connections from PHP have some latency).

If you have no idea what I’m talking about, read on.

WordPress has a built-in object caching API. It is usually used to store complex data objects or HTML structures which are computationally expensive to create on the fly. By default, the engine is implemented in PHP memory. That means that objects don’t persist in-between requests. The only benefit there is if you’re accessing the same objects multiple times on one request.

Enter persistent object cache backends. These backends store the data objects between page loads, which saves your server a lot of time and speeds up the user experience. APC is both an opcode cache (which speeds up PHP in general) and an in-memory key/value store which persists between page loads. If you have it installed (or can install it), I highly recommend that you do so. Unfortunately this probably won’t be available to anyone on shared hosting — VPS/dedicated only. Once you have APC up and running, as confirmed by phpinfo();, install the APC Object Cache in your WordPress content directory. It is a special kind of plugin, and will not work if placed anywhere else. It also needs to keep its name: object-cache.php

You should notice improved page load times! I’ve seen it improve page generation time 10x.

And what about Batcache? Batcache is a whole-page or “HTML output” caching engine. It stores complete web pages and saves them for later. It needs a persistent object cache backend to function. Furthermore, it needs an object cache backend that supports incrementation (counters, to measure how much traffic each URL is getting), and that does its own object expiration. Memcached has fit the bill, and is the preferred solution for multi-web-server WordPress installs. Now with the new version of the APC Object Cache, there is a preferred single server solution as well.

Note: W3 Total Cache users need not apply — it handles its own object caching, including support for APC.