Pull Request-Driven Development

At my new job, I’m working on a project that uses some different
processes than the project I was on at my last job. I’m finding the
differences interesting, and have been thinking about the forces that
would push a team in one direction or another.

Background

Process

Both projects use similar agile-style techniques: test-driven
development (TDD), pair-programming, iterative development, etc. I
would guess that both projects are similar in size (both code an
feature-wise), though that’s really hard to compare because they use
different languages and frameworks.

Team Composition

The new project has probably 3x more people working on it than the
old project. Many of the developers on the new project are relatively
new to the project, and some are even relatively new developers. The
old project was pretty top-heavy in terms of development experience
and longevity on the project.

Age of Code

Much of the code in the old project has been around for 15-20 years;
the new project is not that old. That explains why the codebases are
similar in size even though the team sizes are so different. I expect
the new project will become quite a bit larger over time.

Version Control

The new project uses Git and GitHub for all development. The old
project is migrating from Subversion to Git, but also uses Store, the
built-in version control system of Visualworks Smalltalk.

Deployment

The new project is a web application. The live site is updated
whenever changes are committed to the master branch.

The old project is software that runs on industrial equipment; our
builds would always produce an installable CD image, but we actually
deployed to the field much less frequently than that.

Development Style

Branches

On the old project, almost all work was done directly on the trunk (or
“master”, if you prefer). We would create branches from time-to-time,
but we did our best to work right on the trunk and keep everything
stable. This forced us to work in small increments and find ways of
keeping work-in-progress away from the end users until it was done
(using “feature flags” and similar techniques).

The new project does everything on branches. There are some
long-running branches for major new features with minor story branches
off of those. Nothing gets committed directly to master; master is
only updated by merging in another branch.

Pull Requests

On the old project, we considered pair programming to be a sufficient
form of code review. Any pair could directly commit to the trunk when
they were ready. If any code was developed solo, then we’d ask a
colleague for a code review first.

On the new project, all code goes through a pull request, even if it
was developed by a pair. Pull requests are reviewed by at least one
other developer, often more.

Testing

Both projects have a way of deploying running software somewhere
“safe” for additional testing. The new project uses internal staging
servers; the old project had test equipment.

Impressions

Given a sample size of two, I won’t try to draw any deep, far-reaching
conclusions from my experience. But I can talk about my impressions
so far.

I’m getting used to working with lots of branches. Git does make that
pretty easy; trying to do it in Subversion or Store would be much more
difficult. But I’m already running into places where I want code from
one not-yet-merged branch to be available on the branch I’m working
on. Merges can also be a bit of a challenge, especially if you
weren’t directly involved in writing the code that needs to be merged.

By far, the biggest adjustment has been having to have everything go
through pull requests to make it into the product. I find that this
really hampers flow.

I finish work on a feature, commit it to my branch, and push it up to
GitHub. Then I have to create a pull request and wait for someone to
have time to review it. Meanwhile, I start working on the next
feature. Once the original PR has been reviewed, then I have to go
back to that branch, remember what I was doing, and address any
comments from the review. This can repeat several times before the
feature finally gets merged. I’ve had 4 or 5 open PRs at a time
already, and I find it difficult to keep everything straight.

This style of development also has a heavy impact on the developers
who have been on the project the longest. They’re the ones with the
deep knowledge of the codebase, and so they’re the ones best suited to
review most of the PRs. That gives them a lot of extra work to do,
and also means that sometimes the PRs can back up waiting for them to
be available.

That said, I understand why the new project uses pull request-driven
development, and I think it’s the best option given the constraints.
There are lots of developers, and many of them, including myself,
don’t yet have deep enough knowledge of the codebase to be able to
make good decisions about the wider implications of the code they’re
writing. On the old project, we had enough experts around that one of
them was your pair partner for almost every story. On the new
project there aren’t enough experts to go around, so having them
review pull requests solves that problem. As a newcomer to the
project, I really appreciate having the extra eyes on my work, because
it’s easy for me to do something that doesn’t work in the larger
context of the project.

But it still feels like it slows things down and I wish there was a
better solution. Hopefully, as the team grows in their knowledge of
the codebase, and in their development experience, we’ll be able to
speed things up a bit.