WordPress Workflow Tips: Using Subversion Externals for Plugins, Themes and Core

Subversion Externals for WordPress Projects

I’m pretty sure most of you are familiar with version control, and that it’s best practice to start each new project in version control, and not “add it sometime later.” Version control will help you manage changes to your code, and have revisions which you can easily roll back to.

Although my favorite version control software is Git, today we’ll talk about Subversion, and WordPress developers know that WordPress itself, as well as the plugins repository and the themes directory, are hosted in public Subversion repos. As you’ll see, this makes it incredibly easy to access core, themes and plugins using external references.

It’s a great idea to keep all of your code under version control, including WordPress core, the themes and plugins that you use. However, themes and plugins, as well as core, are already under version control in a different place, so to avoid redundancy, and extra maintenance work, we can use external references, which are more often referred to as svn:externals in the world of Subversion, or submodules in Git.

In short, an external reference is an entry in your own version control repository, which points to a different place, similar to a symbolic link in your operating system. When running svn update, Subversion will follow these links and grab the source code from those external repositories, without having to keep them under its own version control.

That might sound a little confusing, so let’s take a look at some examples, which will hopefully clear that up.

Plugins as Subversion Externals

Suppose I’m working on a typical WordPress project, and have got some themes and plugins in my Subversion repository, like this:

/public_html/
  - wp-content
    - themes
      - twentyten
      - twentyeleven
    - plugins
      - akismet
      - jetpack
      - bbpress
  - wp-includes
  - wp-admin
  - ...

Note, that the whole public_html directory is under version control.

Let’s say Akismet just shipped a new version, and my WordPress dashboard prompted me to update. When updating the plugin, WordPress will replace the old Akismet plugin files with the new files, thus, my files are now out of sync with my repository. In order to bring them back in sync, I have to SSH onto my server, and commit the new and modified Akismet files back to the repository, which is a pain.

Luckily, we can get rid of such pain by using svn:externals. So lets remove the akismet directory from our repository, and add an external reference to the Akismet plugin, like so:

cd public_html/wp-content/
svn rm plugins/akismet
svn commit -m "Removing Akismet from the repository."
svn propedit svn:externals plugins

Which will launch a text editor (typically nano or vim), where you can add the external reference to the latest version of Akismet from the WordPress.org plugins repository, like this:

akismet http://plugins.svn.wordpress.org/akismet/tags/2.5.6/

Save and quit your text editor, and run svn update. This will update your files from your repository as it usually does, and then update its external references, so you’ll probably see something like this:

Fetching external item into 'akismet'

Followed by the addition of an akismet directory in your plugins folder, with the Akismet plugin source files. These files are not under your version control, they’re just copied over from WordPress.org repository.

Now, when Akismet ships a new version of their plugin, say 2.5.7, you don’t need to update from your WordPress dashboard, you’ll just need to edit your external references, and change that tag to 2.5.7. Then run svn update and Subversion will pull in the new version for you, replacing the old files.

Let’s do the same for the Jetpack and bbPress plugins. Remove them from the repository, and add them as external references instead:

cd public_html/wp-content/
svn rm plugins/bbpress plugins/jetpack
svn commit -m "Removing bbPress and Jetpack from the repository"
svn propedit svn:externals plugins

Akismet is already an external reference, so let’s just add the two new ones:

akismet http://plugins.svn.wordpress.org/akismet/tags/2.5.6/
jetpack http://plugins.svn.wordpress.org/jetpack/tags/1.7/
bbpress http://plugins.svn.wordpress.org/bbpress/tags/2.1.2/

Now run svn update and Subversion will pull in the Jetpack and bbPress plugins for you, directly from the WordPress.org repository. If you’re wondering where I got those URLs, browse to any plugin on WordPress.org and click the Developers tab. You’ll see an svn link to the current version.

Themes as Subversion Externals

You can do the exact same thing with WordPress themes, which are hosted in the WordPress.org repository, such as Twenty Ten and Twenty Eleven:

cd public_html/wp-content
svn rm themes/twentyten themes/twentyeleven
svn commit -m "Removing Twenty Ten and Twenty Eleven from repo."
svn propedit svn:externals themes

Now add the references to Twenty Ten and Twenty Eleven, like so:

twentyten http://themes.svn.wordpress.org/twentyten/1.4/
twentyeleven http://themes.svn.wordpress.org/twentyeleven/1.4/

You’ll find the link to the Subversion repository in the Developers tab of any theme on WordPress.org. Make sure you pick the latest stable version, by comparing the version numbers in the repository, to the version number displayed on the theme page. It is not always the last one, since themes go through a review process, and some versions might not be approved, but still listed in Subversion.

Now, when you run svn update from your wp-content directory, you’ll see that Subversion will pull the external references for your themes and plugins. There! You no longer have to maintain themes and plugins from WordPress.org, in your repository! Just svn update every once in a while ;)

WordPress as a Subversion External

You won’t be surprised that, since WordPress is also hosted in a public Subversion repository, it can be an external too! It’s slightly more tricky than with themes and plugins, but definitely handy. In this particular case, the external reference needs a folder of their own (otherwise you’d have to list all core files as externals), so your working directory has to look somehow like the following:

/public-html/
  - wp
  - wp-content
    - themes
    - plugins

This means that you’ll have to setup WordPress in a subdirectory, and move your wp-content directory outside of WordPress core (though as an external, WordPress will still have one of its own).

Now, let’s remove the wp directory and place it as an external reference to our public_html folder instead:

cd public_html
svn rm wp
svn commit -m "Removing WordPress from repo."
svn propedit svn:externals .

Note the dot at the end of the call to propedit, meaning we want to edit the property for the current directory. Then, in the text editor, let’s add our reference:

wp http://core.svn.wordpress.org/tags/3.4.2/

After saving and quitting your text editor, run svn update from the root of your repository, and you’ll see that Subversion will grab the WordPress core, and your themes and plugins references. Neat!

Whenever you need to upgrade WordPress, you’ll just change the reference to point to the new version, and update again. You don’t need to delete the files every time you update an external reference, Subversion will do it for you. Also, when updating WordPress, don’t forget to visit the admin page, in case there are updates to the WordPress database.

At this point, you should no longer be maintaining WordPress themes, plugins or even WordPress itself in your own Subversion repository. Let WordPress.org do the work for you, while you focus mainly on your own code. I mentioned in an earlier blog post, that you can use GitHub projects as subversion externals too, which is pretty awesome.

If you’d like to learn more about Subversion externals, visit this page.

So what about you? Are you using version control for your WordPress projects? Do you prefer Git or Subversion? Do you currently use, or plan to use external references? Please share your thougts via comments, and thank you so much for stopping by!

About the author

Konstantin Kovshenin

WordPress Core Contributor, ex-Automattician, public speaker and consultant, enjoying life in Moscow. I blog about tech, WordPress and DevOps.

4 comments

  • This is a really good idea. Would like to try it out, however I would much rather be using Git and its submodules (as I don’t have an SVN server).

    I can use the GitHub mirror to add the WordPress core as a submodule, but I guess it won’t be possible to do it with the plugins unless I set up a mirror of all the ones I want, which would be a bit too much effort!

  • Using externals for plugins and themes is a great idea and having the WP core that way is awesome too. Thank you for explaining the mechanics.

    Is there a way to have the WP core as an external reference in a Multi Site setup (when WP has to be in the root dir)?