Last week we covered how to publish a WordPress plugin using Subversion.  But many of us aren't using Subversion.  I know that after I started using version control, I quickly graduated to Git and Mercurial for managing distributed development.  It makes it easier for me to collaborate with others, and makes it easier for other people to take my ideas and run in new directions.

Actually, those two reasons most of us like Git and Mercurial are probably the two reasons keeping WordPress in Subversion.  But I digress ...

Here is a step-by-step tutorial for publishing a WordPress plugin using Git.  To follow along, you'll need:

  • A WordPress plugin to write
  • Git
  • A WordPress.org account

First and Foremost

The very first step is to create an account on WordPress.org.  You’ll use this account to control your plugin, post to the support forum, and edit the Codex.  Chances are that you already have an account.  But if you don’t, it would be a good idea to create one.

Get Hosted

Next, you’ll need to ask the WordPress.org team to host your snazzy new plugin.  All you need at this point is a name and an idea.  It can take anywhere from an hour to a few days to get your application approved, so don’t worry if you don’t have any code written yet.

Using Git

If you haven't already, you should read my tutorial on working with Subversion.  It holds some great reasons for why you should use version control in the first place, and introduces a great GUI for working with Subversion.

There's a similar GUI for Git called TortoiseGit.  I use it for a lot of my GitHub and Gitorious work, but I'm not going to use it for this tutorial for reasons to be explained above.

So if you haven't already, download Git.  It includes both a command line application (Git Bash) and a user interface, at least for Windows users (Git GUI).  Trust me, they'll come in handy.

Clone the Repository

With Git, you make a local clone of a remote repository, make all of your commits locally, then push your changes back to the remote.  The convenience of this is that you can do most of your development offline but keep track of your changes just like you did with Subversion.

Luckily, Git even has a tool that allows you to clone a Subversion repository as a Git repository.  It's called "git-svn."

First, find a place on your computer where you want to keep your plugin, and create a new folder for it – I keep most of my stuff inside a /WP-Plugins folder.

Right click on /WP-Plugins and select "Git Bash Here" to open the command line client.  Basically, this opens a shell window and automatically drops you right in the folder.

Be very careful when you clone your local repository.  It might take a while ...

WordPress keeps all of its plugins in the same Subversion repository.  There are over 24,000 plugins in the repository, covering a total of almost 780,000 revisions.  I accidentally cloned the entire repository once and it took several hours.

To clone your repository, run the following command in Bash:

[cc lang="bash" width="580"]git svn clone -r697143:HEAD -s --no-minimize-url http://plugins.svn.wordpress.org/my-cool-plugin[/cc]

Let's break this command down just a bit:

  • [cci]git svn clone[/cci] This is the basic command required to clone an SVN repository using Git
  • [cci]-r697143:HEAD[/cci] This flag will clone starting from revision 697,143. Use whatever revision you want - the later the better. When you first gain access to your repository you can check the revision number it's currently at. Use that to skip the first ~700k lines of unnecessary history.
  • [cci]-s[/cci] Clone the repository assuming the standard trunk/tags/branches directory structure so many of us use with SVN.
  • [cci]--no-minimize-url[/cci] Don't shorten the repository URL, instead clone from the subdirectory you've specified - your plugin.
  • [cci]http://plugins.svn.wordpress.org/my-cool-plugin[/cci] The URL for your new plugin.

This clones your plugin repository into a /my-cool-plugin directory.  The "-s" flag tells Git to expect the standard trunk/tags/branches folder layout and the "--no-minimize-url" flag tells Git to pull down only your plugin rather than the entire repository.

Git will take a while to think Git has to look at the whole repository to pull in all of your changes ... so it could take a while.  Go grab some coffee while you wait.

Create a First Version

If your plugin's all ready to go, feel free to skip ahead to the section on pushing your changes.  Otherwise, start writing something in your empty folder.

As you make changes to your plugin, you can commit whenever you want within Git.  Just run the following in Bash:

[cc lang="bash" width="580"]git add .
git commit -m "Your commit message"[/cc]

This will add your modifications and commit to your local copy of repository.

Remember: You're working entirely on your machine, so these changes won't be seen by the rest of the community until you're ready.  Commit as often as you want and as often as you need to.  If you ever need to go back and undo something, you won't regret it.

Synchronize

When you're ready to publish, you have to do three things:

Update

You always want to make sure you're working with the latest section of code.  If you're like me, you might end up working on multiple machines ... to make sure you don't accidentally roll back a release when you push, you'll first need to update your local repository.

If we were working with a typical Git repository, we'd run [cci lang="bash"]git pull[/cci] to get the changes.  But since we're working with Subversion, things are slightly different:

[cc lang="bash" width="580"]git svn rebase[/cc]

This command tells Git to re-fetch your repository from Subversion and rebase your changes on top of anything that's changed in Subversion.  In a sense, you can think of this as taking your entire block of changes, exporting a patch, running [cci]svn up[/cci], then re-applying your patch.

That's not really what happens, but it's close enough.

Push

Now we know our repository is up-to-date and we're ready to commit our changes to the Subversion repository.  In the world of distributed version control, this is called a push.  Basically, you're pushing your changes from the local clone back to the original repository.

If you're working with something on GitHub, you can just run [cci]git push[/cci].  Once again, though, remember that with Subversion things are slightly different:

[cc lang="bash" width="580"]git svn dcommit[/cc]

The [cci]dcommit[/cci] command tells Git to push all of your local changes into the remote Subversion repository.  It'll think for a minute, package things appropriately, then start talking to WordPress' server.

At this point, Git will ask you for your WordPress.org credentials.  Make sure you enter your username and password or this won't work.

Tag

The "/trunk" folder of your plugin is now up-to-date.  But remember from our discussion on Subversion that the downloader looks in your "/tags" folder for releases.  Conveniently, Git will copy your "/trunk" folder into the right tag for you.  Just run:

[cc lang="bash" width="580"]git svn tag "1.0"[/cc]

This will copy everything in /trunk into /tags/1.0 on the server.  If you were to do a standard Subversion checkout, you'd see the folder sitting there with all of your changes.

Why Didn't We Tag First?

When we were working with Subversion, I encouraged you to tag your release before changing the readme file in trunk.  That's because every time you commit to trunk it's immediate.  If you edit your readme file today, but don't plan to release until next Tuesday, things can go horribly wrong.

With Git, though, that doesn't happen.  You can change your readme file or update anything you want and commit locally as much as you want.  Nothing happens on the server until you use [cci]dcommit[/cci] to synchronize your changes.  So long as you always remember to tag your releases, you should be just fine.