## Git & the WordPress Repository

A while back I wrote an article on WP.Tuts on using Git to publish plug-ins on the WordPress repository. The wordpress.org plugin repository runs on Subversion, but I, for various reasons prefer to use Git. It’s also incredibly useful for putting your plug-on GitHub or BitBucket where you can collaborate with other developers.

The trouble is two-fold:

• Git & SVN don’t play particularly nice
• My local (and Github) Git repository are focussed on development, the wordpress.org is solely for distribution.

Let me explain the second point a bit more. If you’ve worked with Git you’ll probably be aware that you are to commit little and often (see for example, Tom McFarlin’s recent post). But the WordPress repository is for distribution – they don’t need or want all the those commits.

In fact, as you probably know, Otto has said:

“If I catch you at it [pushing each commit separately], then I will ban you from WordPress.org. The SVN only needs your final working version committed to it, not the entire history of the hundreds of changes you made using Git. Flatten your changes to a single commit.”

Now in my original article I outlined a workflow in which you develop in a ‘development branch’ and then when ready to release something, merge and squash those changes into your master, before pushing to the SVN. Unfortunately, beyond you current ‘development branch’ you loose all your history.

## A Better Workflow

I’m not sure why this didn’t occur to me earlier, but by essentially reversing this workflow, we can preserver our history, but also commit to the WordPress subversion times only once or twice for each tagged release. We do this by developing in the master (or some other branch), and merge and squash into a release branch. We push from the release branch to the SVN repository.

This isn’t actually different from what we were originally doing since from a git point a view (but not a Github point of view) the master branch is just another branch. But we do need to set up our release branch to track the remote SVN repository.

## How It Works

(I’m posting this as much for my own reference as anything else). I’ll assume that you’ve been working on a project for some time, and let’s suppose its in Github, but now you want to publish it to the WordPress repository. Once you’ve been accepted you’ll receive an e-mail containing a link to your wordpress.org hosted SVN repository, something like http://plugins.svn.wordpress.org/your-plugin-name.

### Step 1: Clone the SVN Repository

The WordPress repository is big, to clone our plug-in we’ll first tell git where to find it. The following will get the first log of our SVN repository (when it was originally added):

 svn log -r 1:HEAD --limit 1 http://plugins.svn.wordpress.org/your-plug-in-name


It will think for a while and then you should see something like this:

 r651844 | plugin-master | 2013-01-13 05:33:38 +0000 (Sun, 13 Jan 2013) | 1 line


That rXXXXXX (revision) number is what we’ll use to ‘find’ our repository. It’s not necessary, but speeds things up somewhat. So next we clone our repository:

  git svn clone -s -r651844 --no-minimize-url http://plugins.svn.wordpress.org/your-plugin-name


This should take a few minutes, but it will initialise a git repository with the folder your-plug-name. Let’s view the branches in that repository:

  cd your-plugin-name
git branch -a


This should list master (your local repo – this will probably be starred as its the branch you’re in currently). As a remote repository it will also have (the SVN) remotes/trunk. Currently our repository is empty (since our plug-in’s SVN repository is). (If it wasn’t we could fast-forward through the changes and have an up-to-date copy.)

### Step 2: Pull Our Project From Github

Our plug-in is currently sitting on Github, so the idea is to pull it into our newly created repository. So let’s add our Github repository (which I’ll call origin – but it can be anything) and then pull it into our repo:

 git remote add origin git@github.com:your-github-username/your-repo-name.git
git pull origin master


Our plug-in should now be in our repository, along with its complete history. We can commit further changes if we desired.

### Step 3: Create A Release Repository

Next create, and checkout our release repository:

 git checkout --track -b release remotes/trunk


This now tracks our SVN trunk sitting in the WordPress Repository. Everything is now set up. We can return to the master branch and make any changes if desired.

### Step 4: Committing to SVN Trunk

Let’s suppose we’re ready to push to the SVN branch the latest and greatest changes we’ve made in our master branch. We checkout our release branch and merge (and squash!) our master branch

 git checkout release
git merge --squash master


Note: after the first merge you’ll notice that you start getting merge conflicts – assuming you don’t develop on the ‘stable’ branch, these aren’t really conflicts at all, and its much easier to do the following which is the same as the above, but any ‘conflicts’ are automatically resolved in favour of the master branch:

 git merge --squash -Xtheirs master


Just to be sure we don’t loose anything on SVN we can perform a rebase (though I find this is never necessary and if you’re the only commiter you’ll probably find this too)

 git svn rebase


Hopefully you’ll get a message saying Current branch master is up to date. Then we’re ready to push:

 git svn dcommit


This may take a few minutes.

### Step 5: Tagging A New Release

Our trunk is now up to date, but if we were tagging a new release (and so had updated the plug-in’s readme.txt stable tag) we also need to create that tag. This is very simple, for tagging “1.6.1″ for instance:

 git svn tag "1.6.1"


Again, this may take a few minutes. You shall probably receive an e-mail notification from WordPress.org too. In about 5 minutes time the WordPress plug-in repository should be updated with your new release.

1. Wow, pretty nice article and quite useful. I wonder if WordPress will ever switch to Git….

• Thanks! I sure hope so (at least for development). The repository will probably always be SVN – at least, I can’t see them making it more development focussed – since it is, after all, a distribution repository.

I heard of some ideas floating around about making the WordPress repository (or something alongside it) more ‘social’ – in that you could make pull requests etc (something like GitHub) – but it was blue sky thinking!

2. Thanks, may come in handy later. I have to admit, though, that I’m really wondering whether to still use the official WP plugin repository. Just sticking to Github is so much easier, faster and cleaner.

• Definitely, Git and GitHub/BitBucket I find are the best things to develop on. But the WP repository gives you stable (and free) hosting for your plug-in – and an large audience ready to use your plug-in. The WP repository lacks all the frills and convenience of GitHub, but without it I doubt my plug-ins would see much attention!

3. I prefer Git to SVN while developing, but have to use both (one for development and one for distribution, as you said in the post). Using them together on the same code base is a pain for me. You post seems to solve it, but it’s quite hard to remember all those commands. I think it’s not worth spending too much time learning how to make these tools working together, instead of that focusing on development.

Currently, I make 2 folder of plugins, one for Git and one for SVN. It’ll take more space on my computer, but it’s easy to commit to both repositories: just copy & paste, then use normal Git + SVN tools. It just works like a charm

• Admittedly this is why I made this post, as a reference for myself so I could find the commands again pretty easily!

The drawback of this approach is if you already have a Git repository, but you’ve only just set up the SVN repository. In this post I’ve solved it by setting up a blank Git-SVN repository and then pulling into the original Git repository. Seems a bit dirty – but like you say, it works, and there’s only so much time you can spend on tools that help you code before you need to actually code!

Regarding having two separate folders. I know its possible ( Rarst does this) to have them in the same folder, but ignoring each other. So works the same way, but without the need to copy & paste.