The Why Behind the Code
Tags: git, programming, productivity
Published: 2023-08-22 20:25:24

Do you know why microservices architecture is so popular? Because it’s easier to rewrite the whole service rather than inspect the code to find the bug causing crashes in production. 

That might be a joke, but I’m sure you'll agree that looking through the code to fix a bug or add a feature is something we sometimes prefer to avoid. Especially when we struggle to understand why this code even exists. I mean, it’s easy to understand what the code does, as it’s right there on the screen. But often, we don’t understand why it’s written that way. Is it a workaround for something? Does it fix some problem in a rare case? What happens if I delete this part of the code? And how can we decide?

People who've worked with me know my strong opinion on making Pull Requests, especially regarding code commit messages. In short, I believe that the commit message must answer the question “_Why_” the commit was made, with the understanding that the code answers the “_What_” it does. Most developers don’t share this view, and here I’m explaining my stance and trying to persuade you to adopt the same approach.

In fact, I wasn’t always so meticulous about commit messages. Many years ago, I found it perfectly acceptable to leave a message like just `fixing bugs`. And that’s what I typically see when I open someone else's code.

Here's a list of messages that represent what we usually see:

- `add CanUpdate to DbConnection interface`
- `fix for when size is 0`
- `fix use_react to support absolute paths`
- `fix web_base.py`
- `fix show history output`
- `fix dependency`

These messages, taken randomly from public GitHub repos, represent common types of commit descriptions. They seem like short summaries of what was done in the commit.

Such commit messages are like an email subjects, which for most people are simply recognizable label that help distinguish between emails in a list. 

While these commit messages could be used as reference points for standup calls or weekly reports, they have no use after those meetings.

However, after years in software development, I've learned the hard way when commit messages truly come into play. They are a last-resort tool, something you refer to when worried that a code change might break something else, or perhaps after a change has unexpectedly caused a crash elsewhere. That's when you run a `git blame` to understand the reasons behind the existing code. Sometimes, you're the original committer, but you might not recall the reasons for writing the code that particular way.

Let’s accept it that a self-explanatory code is a unicorn and code comments are almost never enough to understand it. More to that, even if you in this rare situation with a clean code and good comments, none of this can explain a code change as a whole. It cannot explain a relation between different parts of the code. To link these parts and answer the questions, the commit message should be used. It's the only space suited for this purpose.

Think of the commit message as a medium to communicate with a future developer, or even a future version of yourself. It's a message that can explain multiple changes across several files, providing the rationale for those changes.

I hope my point is clear and resonates with experienced developers. But how should one write these commit messages?

For me, any code change is in response to a problem. Every commit (a “_solution_”) addresses something specific in mind (a “_problem_”). 

Even if you're just updating a dependency, you're likely addressing concerns about outdated, incompatible, buggy, or slow code in the current version. Or you see it as a problem maintaining a code depending on an outdated library. Such an update solves the problem by upgrading to a newer version. If you're refactoring, you likely see issues with the current code's readability, maintainability, flexibility, etc.

So here's my suggestion: state both the problem and solution in the commit message. Like, `Problem: what I wanted to solve; Solution: how I solved it`. 

I’m not an inventor of this approach, of course, but an advocate for it.

When you adopt this approach, you might find that it simplifies the commit message drafting process. You start recognizing that you always approached commits as answers to problems, but struggled with how to write both problem and solution as one phrase. It’s okay to use two distinct phrases, and it can be easier to write them this way.

Here is an example of what I suggest:
 
```
Problem: egress/ingress naming for log config is too confusing
Solution: rename to request/access logs
```

This approach is more informative than a vaguer message like:

```
renamed egress/ingress logs config to request/access logs
```

In the latter case, you might just shorten it to:

```
rename logs config
```

And it stops providing as much information as the original. Also it doesn't answer _Why?_ anymore.

It's very tempting to put just a _solution_ part describing _what_ is inside the commit. I made this mistake many times, and see it very often others do. Developers, when they asked to write a commit messages as _problem+solution_ start writing just _solution: what's inside the commit_. That's not helpful! 

I agree, though, that some commits are straightforward enough that their intent is clear. In such cases, I think, it's acceptable to omit the obvious part. For example, when upgrading an outdated library, stating `problem: netty 4.1 is outdated` during a `git blame` would say enough about the solution.

Like in my commit above regarding config names, the “_solution_” part might have been redundant. However, almost 50 files were modified in that commit, so I chose to provide a comprehensive description to manage expectations.

What I suggest now is adopting this approach. Just think about the problem you solved, and what is the solution. Not necessary to push very hard and be formal, but always try to answer “_Why_” the commit was made, not what is inside it. Just put both in the commit message, without trying to save the characters. And you’ll notice how it improves your process and way of thinking. Plus makes it easier to maintain the code in future.

PS Please share your opinion: https://twitter.com/splix/status/1694084487221522583