Perfect git-svn for WordPress plugin development

WordPress plugin developers need to use subversion to commit their plugins to the WordPress.org repository. And because many developers are using GitHub in their development, it is needed to interwork between Git and Subversion. Though there is a way to make a script program including both git and svn commands, git-svn is a option I like to use because of its simplicity.

After using git-svn and making some commits in plugin development, I learned key points for a happy workflow. I’ll introduce them in this entry and hope it will help you. Even if you are not a WordPress plugin developer, it might help you when you use git-svn.

This article is assuming your basic knowledge about git and svn.

Best Practices

To sum it up, here are best practices I’ve learned.

  • You have to execute ‘git svn dcommit’ on the master branch.
  • When you make a new release, keep master, remotes/origin/master and remotes/trunk branches pointing to the same commit.
  • To do so, execute ‘git push’ after ‘git svn dcommit’ while releasing.
  • When you execute ‘git merge’ to merge working branches into master branch, add the –noff option to ‘git merge’. You can avoid frequent commits to SVN repository by doing so.
  • You can also manage ‘assets’ directory with git-svn.

Now I’m getting into details.

Git svn dcommit on the master branch

To use git-svn comfortably, you need to know a behavior of ‘git svn dcommit’. The ‘git svn dcommit’ command makes a new commit as a replacement of the current commit like ‘git commit –amend’ command. After making a new commit, ‘git svn dcommit’ makes the current branch and the remotes/trunk branch pointing to it. See the following picture showing trees before and after git svn dcommit.

svn-dcommit

Master and work branches were pointed to the same commit before ‘git svn dcommit’. But after the ‘git svn dcommit’, the work branch is now in parallel with master.

Because of this behavior, if you do ‘git svn dcommit’ on a branch other than master, master will go parallel to remotes/trunk branch just like the work branch in the picture. It will be a beginning of chaos.

Git push AFTER git svn dcommit

Regarding ‘git push’, if you execute this command just before ‘git svn dcommit’, remotes/origin/master branch will go parallel like a previous example even though master points to the same commit as remotes/trunk. This is why we have to do ‘git push’ after ‘git svn dcommit’.

Why –noff option?

Basic idea is in a stackoverflow topic. Maybe you like less frequent svn commits than git. Then you need that workflow.

Assets directory

You can manage the ‘assets’ directory in git. See details.

Sample Scenario

I’ll give you a following scenario for example.

Check your first revision number by svn.

svn log http://plugins.svn.wordpress.org/standard-widget-extensions

Make a new git repository by cloning svn repository using the revision number (r630258 for me).

git svn clone -s -r630258 --no-minimize-url http://plugins.svn.wordpress.org/standard-widget-extensions standard-widget-extensions

Then fetch it.

cd standard-widget-extensions
git svn fetch
git svn rebase

Make a remote branch on GitHub.

git remote add origin git@github.com:blogger323/standard-widget-extensions.git
git push origin master

For daily development, make a work branch named as ‘work’. You could push it to GitHub if you like.

git branch work
git push origin work

Now you can work on a local ‘work’ branch.

git checkout work
(...and do your work)

When it’s time to release, merge your work into the ‘master’ branch.

git checkout master
git merge --no-ff --edit work

Now it’s time to update the subversion repository. I’d like to say again that you should execute commands on the master branch and in this order to avoid chaos.

git svn dcommit
git push origin master

Tagging on both subversion and git repositories.

git svn tag 1.0
git tag 1.0
git push origin --tags

At the end of release work, reset work branch position pointing to the current commit.

git checkout work
git reset trunk
git push origin work

Now every branches are pointing to the same commit. Isn’t it worth to try?