Using Git for WordPress Development SCM Instead of Subversion

Git is a distributed version control system. This means that every git clone is a full repository with complete history and revision tracking. Git differs from Subversion because Subversion has one central server and the clients just commit to it. This is why git is so much easier to use for ‘social coding’ and that is where Github spawned from.

This is why I prefer to use git and Github for the source code management and use the WordPress svn repository only as a distribution channel. That works for me, easy to use source control but also a distribution channel that’s accessible to the users. WordPress try to make you solely use Subversion – but you don’t have to!

However it’s not so simple to just use git for WordPress plugin development because the Plugin Directory on wordpress.org is a Subversion repository. Git and Subversion don’t play entirely nicely with each other but it is possible to get it to work.

Dependancies

You are going to need to have git and svn installed (you only need to run one svn native command – but that saves a lot of time and as worth installing svn for).

Download Git from git-scm.com, or you can use a package manager if you are on Unix

Getting Your Repos In Sync

First grab the svn log for your WordPress repo. This is the only svn command you ever need to run and you only need to use it once. Git can handle all of the rest of the svn committing and tagging.

svn log http://plugins.svn.wordpress.org/markdown-formatter

(Replace the address with the address of your repo). This will print you a list of all the commits to the svn server. If you are starting development of a new plugin there should only be one, however if you are continuing development of an existing plugin there may be many entries. You need to look for the earliest commit (it should be by ‘plugin-master’).

You need to use the revision number (r412486 in my case) for the next command. Now we will clone your WordPress svn repo into a git repo.

(The black slash will allow you to split a command into two lines). Remember to replace the revision number and address with your one. Now to actually fetch all of the history of the plugin. Again if it’s a new plugin this will be very quick; however for an existing plugin this can take an extremely long time.

cd markdown-formatter

git svn fetch

To test that the fetch worked, run this command and check that all the tags you were expecting are there.

git branch -r

Setting up Github remote

If you plan on using Github for the social side of coding (I recommend you do!) then now’s the time to add the remote. Go to Github and create the repo then grab the address for it. If you aren’t using Github then just ignore the next step and anything that includes push/pull.

git remote add origin git@github.com:olliea95/markdown-formatter.git

Now you need to add the master branch to your Github repo with a simple push.

git push origin master

But this will only contain the first commit (when plugin-author created your svn repo). To add all your other commits and bring Github into sync you need to rebase the master to trunk and push again.

git rebase trunk

git push origin master

You now have your repos all set up! So you can continue with the development using git and Github for all the SCM you need.

Committing to The WordPress SVN Repo

When it comes to releasing a new version of your plugin then we need to svn commit to the WordPress repo – but there are a couple preliminary steps. Check that you have updated your readme for the new version and any other files which contain the version number. Firstly we rebase the trunk.

git rebase trunk

This should run without a hitch… If it did then you are ready to commit to the repo.

git svn dcommit

If your WordPress.org username is different to the username of your computer (highly likely) then just hit enter when it asks for a password and it will give you the option to specify a different username. Then type the password and hit enter. Depending on how many commits you made before the dcommit it could take a long time. Just sit it out.

Once it has been dcommitted you can tag the release.

Tagging

git svn tag 2.1

Obviously replace the 2.1 with your version number. As this copies your entire plugin in the svn repo it could take a little while depending on the size of your plugin.

Now, so we have some consistency between the git repo and svn repo, we want to tag the release in git as well.

git tag -a 2.1 -m 'Tagging 2.1'

git push origin --tags

If you aren’t using Github then ignore the push command. Finally we need to rebase the repo so Github knows we’ve edited the MD5’s (because svn does it differently).

git pull --rebase origin master

pit push origin master

Working With Other Collaborators

If you are working with someone else who is pushing to your GitHub repo, then you can’t use the normal steps to push to svn. This is because of the way that the svn commits work and rebasing. Unfortunately you are going to have to use svn in a different way – the downside to this is that the svn log will not reflect your git commits.

The way to approach this is basically to checkout the svn repo, copy all the files from your local git repo, and then commit and tag the svn release. I have created a shell script that will do this for you, you just need to edit the directories and URLs as needed.

where you replace update.sh with the name of the script and 2.3 with the version number of this new version. Of course don’t forget to update your readme.txt and any other files with the version number in first!

Finishing Up

Now you can begin working on the next release! Just do all the coding and then repeat the Committing to SVN section to release it.

If you ran into any conflict errors as you were doing this, it’s likely the reason was because the Github repo and the svn repo didn’t have a common commit. The easiest way to sort this out is to delete your Github repo and start from scratch. All svn commits will be preserved.

Quick Reference of Git Commands

git add

Adds specified files to the staging area reading to be committed

git commit -m 'Commit message here'

Commits the changed files to the revision history

git push origin master

Pushes the changes to the remote called origin on the branch named master

git svn dcommit

Git-svn will dcommit the repo to an svn server

git svn tag 2.1

Git-svn tags the trunk on the svn repo as a new version

git tag -a 2.1 -m 'Tagging 2.1'

This adds the tag to the git repo

git rebase trunk

Updates the trunk branch with all the changes in the current git branch

git pull --rebase origin master

Complicated one – rolls back your local git repo to the last common commit with the origin remote then applies all the remote revisions then attempts to apply your revisions on top. Just only use it when you need to and refer to the git-rebase man page to learn more