Introduction

I have noticed some interesting phrases used when some colleagues encouraged me to use a branch and Pull Requests, despite the team has in principle agreed on using Trunk-based development and is practising pair programming.

The purpose of this post is to try understand the psychology when these phrases are used, and in turn help consider:

  • the value of PRs based on the contexts
  • the psychological barriers and mental shift required to move from branch-based development to Trunk-based development

There are plenty of opinionated articles that present the pros and cons of both approaches if you are rather inclined to read something of that nature.

For clarification, I have strong preference for and most experience with Trunk-based development, and branches are only for sharing code with my pair during pair rotation or when we don’t have a commit ready but the day has ended. Also, the context of this post is enterprise software development, and not others such as Open Source software development.

Reason 1: “Maintain a cleaner git history”

“Cleaner” has so far meant a few things.

No experimental commits

We were working on infrastructure work, and ended up with a commit history on Terraform that consisted of multiple commits to try things out, and reverting some and all of those changes. The commit history was admittedly not the nicest to read through as it did not convey progress in development but rather a series of experiments.

A neat set of changes

Some prefer to see a merged Pull Request that enables seeing a complete set of changes related to a feature or story next to each other. This also covers the aforementioned case of “experiments” where changes were committed and reverted, as in the end these would not show up in the change set of the PR.

Reason 2: “Easier to see the change set in a PR”

An argument given to me was that it was easier to see the change set on code when we open a Pull Request and look at it on the code repository hosting system web interface.

On the first impression, this seems to be one’s personal preference, and there is not much we could do. Perhaps the IDE interface is just too ugly, too difficult to handle, or switching to the web interface signifies a change in context that enables seeing the code differently.

On second thought, I noticed two possible patterns:

  1. The process of code commit whilst pairing happens very quick, and the thinking occurs only when we look at the PRs.
  2. If sufficient thinking was done before the code commit, the PRs were mindlessly being glanced over and approved by the other. Reviewing PR becomes a complete waste of energy and ceremony.

What I would like to understand

What is the value of a set of commits, instead of a commit? Trunk-based development means that most commits are work-in-progress, every commit goes straight to production, and every commit has the potential to break production. If there is a set of commits, wouldn’t it be a crazy idea if we did not know which exact commit could be problematic?

Personally, merged pull requests also drive me crazy because when the pipeline runs, the source code step only says: “Merged Pull Request #xxx” which means nothing if the pipeline broke and there is no way to immediately see what broke it.

In the case of commits being experimental, it could mean that we were unable to sufficiently validate our changes locally. On the other hand, though, is it also a sign that we indeed have enough confidence to break things and fix them quickly? Or were we simply cheating the system knowing that it was OK to break things rather than keeping the pipeline green for other team members?

Extra: What I really missed from the days when we strictly did not do branches and Pull Requests

The conversations.

I noticed that when the mechanism of pull requests exist, folks would take the option to not pair and create PRs, and PR reviews would be exactly as described in this article – superficial. PRs at their worst create a tunnel vision that delivering software is all about the code, when it is about many other things.

In the environment where we did not have branches (coupled with all other XP practices), through discussions we unearthed all aspects of delivering software. We never rushed to implementing the code, but rather slowed down to discuss why we were implementing a feature, how to implement it (exchanging opinions about code design, and aligned the entire team on code patterns we agreed on, or occasionally respectfully disagree with each other), and even whether the story is really ready for development or does it need more thought from the POs, Business Analysts, and designers.