💡 Delete unused code (and how to retrieve it)

Hello Reader 👋

I hope you are doing well today!

Today, I want to quickly explore the advice of deleting dead code. It's a good and popular one. Yet, it doesn't address one concern: how do you retrieve the deleted code? I'll show you how to.

If you prefer to read that online, I wrote a blog post for you.

Before we dive in, there is something cool I want to share with you: MenderCon is back on May 10th 🤘

What's MenderCon? It's a virtual unconference for people who enjoy working with existing code.

May 10th will be a full day focused on modernizing and improving software systems. From the smallest apps, to the biggest enterprise monoliths. Meet other menders here. Make friends. Expand your network.

There will be some talks too:

  • How a 40-year-old software company keeps its code fresh and maintainable by Haim Cohen and Lainey Hall
  • Clean Code - Strategies & Principles by Abhishek Jain
  • Decommissioning a legacy module progressively, using AST traversal by Adrien Joly—I've watched Adrien's talk in French and it's reaaally good!
  • Unifying UIs with a Design System by John Athayde

The cherry on the cake: the event is FREE, thanks to the sponsors 🍒

You can grab your free ticket here: https://mendercon.com/

I'll be there. I hope you will be too!

Alright, let's talk about dead code now…

Delete dead code.

This is common advice you may be familiar with. The rationale is legit: unused code adds cruft to the codebase, making it harder to read and reason about. Code usually becomes dead after the software has been changed or fixed. Sometimes, dead code is a residue of exploratory sessions, when we are trying to figure out how to implement something.

Sometimes the code is explicitly commented out. Sometimes, it’s unreachable (good IDE can tell you this). And sometimes, it’s tricky to tell whether or not it can be reached—if that’s your case, find a way to monitor when the code is called in production, wait, then get your answer from the logs.

Once you are confident some code is unused, get rid of it. Less code to read and maintain is easier to digest and less error-prone.

But what if we need it?

Some people may ask:

But what if we need it later? It could be useful as a reference.

This sounds like a valid concern, but generally expresses our loss aversion bias—the pain of losing something is psychologically twice as powerful as the pleasure of gaining. We are afraid of deleting code!

There are two antidotes to this, and you may have heard these counter-arguments yet:

  1. YAGNI. The sooner you cut the code, the sooner you reap the benefits of not wasting on maintaining, compiling, testing, and reading it. Moreover…
  2. You can get it back from source control.

The 2nd point is the key to the “delete dead code” advice. With git, you won’t lose that piece of code. So why the loss aversion?

And that’s it. This is usually where the argument ends. Everything was said, no reason to argue more. I’ve sometimes heard this (sound) advice poorly packaged, using condescending words such as “your points are utterly irrelevant since…”—please don’t do that, it doesn’t help 😄

So why people are still reluctant to delete code?

I’ve witnessed it with my own eyes. Experienced engineers, very aware of YAGNI, the smell of dead code, and yet falling for the siren of “let’s just comment it out for now”.

Thus, I dug deeper and after discussing I realized something: they know git could retrieve the deleted code, but they don’t know how to find “some code” that was deleted “somewhere” in the past. Keeping the code in the codebase feels easier since:

  • You are more likely to bump into it when working in the relevant parts of the codebase
  • It will pop up in your regular grep/searches

So the loss aversion problem isn’t fully addressed yet. At least, not until people feel confident it would be easy to retrieve the code at some point in the future, based on partial information.

I know I could retrieve it… but it’s much harder.

The friction is the problem. After all, git blame can tell you the history of a given file or when some code was introduced… But what about code that isn’t visible since it was removed 3 months ago?

Great news: nope, you don’t need to remember which commit deleted the code to retrieve it!

If you are feeling doubtful about how to easily retrieve deleted code from partial information, let me show you how…

How to retrieve deleted code from git logs

Ok, let’s pretend we are working on the Abracadabra codebase—it’s a VS Code extension that implements a bunch of automated refactorings for JS and TS that are missing in this editor…

As you can see, it has thousands of commits. I remember that, at some point, there was a concept of “cursor” that represented the user cursor and which you could put at given positions in the active document. It was removed a while ago, and I vaguely remember the name (PutCursorAt something). How could we retrieve the relevant code from all of the noise? 🤔

Let’s ask the git log:

git log --oneline -G "PutCursorAt"

It very quickly spits out the commits that contain code that matches the PutCursorAt pattern (read more about -G option here):

> git log --oneline -G "PutCursorAt"

36ee67ec Use Write to drop PutCursorAt logic
ac07e7b3 Update cursor to follow moved down statement
79f1bb43 Update cursor to follow moved up statement

Narrowed down to 3 commits. Not bad. In fact, commit 36ee67ec seems to be the one I was looking for. And here’s the diff.

git log -G is your way to find code across the whole git history of the project. The --oneline option is here to make the output slim and to the point.

So you get the idea. Need to find the commit where we got rid of your “daily emails” feature? Try out git log --oneline -G "daily-email".

Do you remember the name of the deleted file, but you are not sure where it was located?

git log --oneline -- **/dailyEmail.ts

How to retrieve deleted code with even less friction

The git command line interface is powerful. But some GUI tools aren’t bad either.

In fact, I’ve found GitUp to be particularly well made—although it’s only available on MacOS. It has a search box that you can use to find deleted code like you would do a regular search in your editor:

But to make it happen, you have to enable Repository > GitUp Settings > Search commit diffs.

There you go: frictionless retrieval of deleted code 🙌

Now you know. And if you come across a fellow developer who is reluctant of deleting some dead code because “deleted code is harder to find”, spread the word, send them this email. They will thank you 😉

Oh, and in case you missed it: Elon Musk wrote that Twitter would "ultimately need a complete rewrite"

To be fair, it's hard to tell from a single tweet if he meant "a progressive rewrite over time" or "a complete rewrite from scratch".

However, the "for no good reason" part is typical. It's a common feeling when dealing with legacy code. And a common fallacy too 😅

If you ever were to deal with a legacy codebase that seems to fall apart at any change, don't go for a big-bang rewrite! A better approach is "the Ship of Theseus" (aka "the Strangler Fig") pattern.

If you want to learn more, I wrote about it: understandlegacycode.com/blog/ship-of-theseus-avoid-rewrite-legacy-system/

Until next time, take care!

Understand Legacy Code

Piles of Tech Debt, no tests, no docs, short deadlines… But you are not alone! Join me and get regular tips, tricks, and experiments to turn unfriendly codebases into insightful ones 💡

Read more from Understand Legacy Code

Hello Reader 👋 I hope you are doing well today! I recently finished reading “Refactoring at Scale” by Maude Lemaire, while on a nice family trip to Toronto, Canada 🍁 Honestly, I found it quite good. It's packed with interesting insights and good advice built from concrete real-life experiences. It has become one of the few books I would recommend to someone dealing with a huge codebase, dozens of engineers constantly molding it, and pressure to keep delivering business value to customers....

Hello Reader 👋 I hope you are doing well today! Do you often find yourself fighting with the intricacies of legacy code or navigating through convoluted programming structures? In his popular “Refactoring” book, Martin Fowler collects an impressive catalog of moves that can transform the way you approach code maintenance and evolution. If you haven’t read it and are unsure what to expect, I’ve written down a high-level summary of what you will find here. Hopefully, that gives you a better...

Hello Reader 👋 I hope you are doing well today! If you had a magic wand, what would you do with the tangled legacy codebase you are dealing with? For many developers, the answer will go along the lines of: Kill it with Fire!!1!Let’s rewrite the whole thing on a modern stack. Hopefully, Marianne Bellotti, the author of the book with such a provocative title, has better options for you. I've read it cover to cover and I will share with you my personal highlights here. P.S. here’s a shareable...