PHPUnit Development Moved to GitHub

Over the Christmas holidays I took a break from translating and editing the book on quality assurance in PHP projects that I am working on to finally migrate the code repository of PHPUnit from a self-hosted Subversion repository to a Git repository that is hosted on GitHub.

How did I get here?

I was staying at Arjen's place in Brisbane in August 2008 and one day we talked about distributed version control. Although I knew the basic concepts behind it, I was not yet convinced enough to take the plunge and try it out. Our discussion changed that, but it was not until my second trip to Australia later that year that I took the initial code for PHP_ObjectFreezer (which I had on my laptop since I started to hack on it together with Stefan on the flight to Atlanta for php|works 2008) and put it into a bzr repository on Launchpad. I grew comfortable enough with bzr quickly, but never really warmed up to Launchpad.

Around that time, I was hearing more and more positive things about Git and GitHub from my peers. So I took the PHP_ObjectFreezer code base and migrated it to Git and hosted the repository and GitHub to experiment with both the tool and the platform. It was a step that I did not regret and all the projects that I started since then are hosted on GitHub: bytekit-cli, phpcpd, phpdcd, phploc, PHP_CodeCoverage, PHP_FileIterator, PHP_ObjectFreezer, Text_Template, PHP_TokenStream.

Why did I do this?

Let me start with a quote from GitHub.com:

  • Git is a fast, efficient, distributed version control system ideal for the collaborative development of software.
  • GitHub is the easiest (and prettiest) way to participate in that collaboration: fork projects, send pull requests, monitor development, all with ease.

Over the last year, I have come to appreciate Git and GitHub a lot and also wanted to use them for PHPUnit.

Sure, I could have used git-svn for bi-directional operation between the existing Subversion repository and Git, but this would have always felt like only going half the way.

The arguments in favour of distributed version control systems are discussed by others far better than I could discuss them here, so I will just quote Ian Clatworthy's paper on distributed version control systems, in which discusses not only the technical differences between traditional version control systems and distributed version control systems, but also the differences with regard to development workflows and developer interaction:

  • Developers can collaborate directly without needing central authority or incurring central administration overhead
  • Developers can still be productive when the umbilical cord to their central VCS repository is broken, e.g. when travelling.
  • Creating and destroying branches are simple operations. This is particularly useful when experimenting with new ideas, e.g. a spike when using eXtreme Programming.
  • Ad-hoc collaboration with peers [is facilitated by] intelligent merge tracking [because] merging early and merging often is both possible and surprisingly unpainful. It is difficult to explain just how much of an impact this can make on how co-developers can work together more easily, e.g. when Pair Programming.

What does this mean for you?

PHPUnit is now hosted on GitHub.

In a nutshell, this means that the development of PHPUnit is now more open than it was before. If you want to contribute, you just need to fork PHPUnit on GitHub and create a topic branch for your contribution. Then let me know about your topic branch and I may or may not merge it.

If you are currently using svn:externals to pull PHPUnit into your own Subversion repository, you need to think about an alternative as PHPUnit's Subversion repository is no longer updated and will eventually go away.

How did I do it?

As this might be of interest to someone who wants to migrate his/her repository from Subversion to Git, here is how I performed the migration.

I started by creating a local mirror of the Subversion repository:

# Fetch Subversion repository
svnadmin create phpunit.svn
 
cat <<'EOF' > phpunit.svn/hooks/pre-revprop-change
#!/bin/sh
USER="$3"
 
if [ "$USER" = "svnsync" ]; then exit 0; fi
 
echo "Only the svnsync user can change revprops" >&2
exit 1
EOF
 
chmod +x phpunit.svn/hooks/pre-revprop-change
 
svnsync init \
  --username svnsync \
  file://`pwd`/phpunit.svn \
  svn://svn.phpunit.de/phpunit
 
svnsync sync \
  --username svnsync \
  file://`pwd`/phpunit.svn

Then I used svn2git for the actual migration:

# Create directory for Git repository
mkdir phpunit.git && cd phpunit.git
 
# Use svn2git to import repository
svn2git \
  --trunk trunk \
  --branches branches/release \
  --tags tags \
  --authors /home/sb/authors.txt \
  file:///home/sb/phpunit.svn/phpunit

After that I had to delete quite a few superfluous branches and tags, but that quickly dealt with. The final step was to create common ancestors for the master, 3.5, and 3.4 branches so that merging becomes easy and painless.

# Create 3.5 and 3.4 branches (in local repository)
git checkout remotes/origin/3.5 -b 3.5
git checkout remotes/origin/3.4 -b 3.4

# Create common ancestors for the master, 3.5, and 3.4 branches
git checkout 3.5 && git merge --strategy=ours master
git checkout 3.4 && git merge --strategy=ours 3.5

git checkout master && git merge --strategy=ours 3.5
git checkout 3.5 && git merge --strategy=ours 3.4

After that I had to delete quite a few superfluous branches and tags, but that quickly dealt with.

At this point I would like to thank David Soria Parra who helped me figure out some details here and there.

Update: GitHub now supports Subversion clients:

svn co https://svn.github.com/sebastianbergmann/phpunit