DEV Community

Cover image for Don't Delete, Archive: How I Safely "Retired" Zombie Code with `git mv` and `_archive/`
oji - building AI in public
oji - building AI in public

Posted on

Don't Delete, Archive: How I Safely "Retired" Zombie Code with `git mv` and `_archive/`

Hey everyone, it's your friendly neighborhood old-timer dev here. As a solo dev building AI trading bots in my spare time, projects can quickly spiral into chaos. A particularly thorny issue I ran into was "zombie functionality" — old scripts and their associated notifications, from strategies I'd long since abandoned, refusing to die.

Lately, I'd noticed a significant amount of noise in my Slack notifications from the bot. It was genuinely distracting. When I finally sat down to investigate, I discovered that some old, long-unused scripts were still firing off more than ten notifications a day. This was my "zombie notification" problem.

This is a subtle but dangerous problem. Critical alerts like "Account balance dropped significantly!" can easily get buried under a flood of meaningless notifications. So, I decided it was time to safely retire these zombies.

How the Zombies Were Born

It's a common psychological trap: as you add new features, you become afraid to delete old code. I think everyone's experienced this.

"What if I need this logic again someday?"
"What if some other script is still referencing it, and deleting it breaks something?"

So, you leave the file as-is, or comment out the entire contents. The result? A proliferation of files whose status (active or dead) is utterly ambiguous.

The main culprit in my case was an old stock screener called canslim.py. I'd completely replaced its logic with a new one (JohnnyScreen), but the task scheduler (in my case, a systemd timer) was still configured to run it periodically.

Consequently, this zombie script dutifully executed every day, sending utterly pointless notifications to Slack like "0 matching stocks today." I had several such scripts, totaling over ten notifications a day. It was insane.

Now, simply running rm canslim.py felt risky. While I could restore it from Git history, it's a hassle. In a solo project where I don't have a perfect grasp of all dependencies, a direct physical deletion felt like a bad move.

The Solution: A Code Graveyard (_archive/)

My solution was to introduce a simple operational rule: the "Code Graveyard" (_archive/).

The process is straightforward:

  1. Create an _archive/ directory within your project.
  2. Instead of using rm to delete unneeded files, use git mv to move them into this graveyard.

That's it.

The key is using git mv. This tells Git that the file was moved, not deleted and re-created. This means its entire commit history is preserved.

And if, by some chance, I ever think, "Actually, I really do need that logic!" I can simply git mv it back to its original location in an instant. This psychological safety net is a huge win.

Here's what the commands looked like:

# Create an archive location within the directory for screener-related files
$ mkdir -p screeners/_archive

# Move the old script to the graveyard, letting git track the move
$ git mv screeners/canslim.py screeners/_archive/
Enter fullscreen mode Exit fullscreen mode

Furthermore, I placed a README.md file in this graveyard directory to document when and why each file was archived. This serves as excellent documentation for my future self.

# screeners/_archive/README.md

# Code Graveyard

This directory contains retired scripts. They are kept for historical reference and can be restored using `git mv`.

- `canslim.py`: Retired on 2026-08-03. Replaced by JohnnyScreen. Backtest showed it was a source of value traps.
Enter fullscreen mode Exit fullscreen mode

Following this procedure, I systematically moved all my zombie scripts to the graveyard. Of course, before doing so, I'd quickly grep for any references from other files and, crucially, remember to disable their entries in the task scheduler.

Lessons Learned: S/N Ratio and Regular Audits

I took three main lessons from this cleanup operation:

  1. Don't delete code, archive it. This was the biggest takeaway. Physical deletion should be a last resort. The combination of git mv and _archive/ is an incredibly effective practice for keeping a project clean while maintaining psychological safety. No more cringing when I type rm -i.

  2. Be mindful of your system's Signal-to-Noise (S/N) ratio. Unnecessary notifications are just noise (N) against the signals (S) of your system's health. By eliminating over ten noise notifications a day, I'm now much more likely to spot truly critical alerts (bot crashes, API errors, margin calls, etc.). In solo dev operations, maintaining a good S/N ratio is vital.

  3. Regularly audit your codebase. I only undertook this major cleanup because I was fed up with the noise, but this should ideally be a routine task. Even for a solo project, I'm making it a rule to hold a "Code Graveyard Festival" at least once a quarter.

Time is a precious commodity when you're a part-time developer. That's why building in maintainability mechanisms like this from the start pays huge dividends later. An hour of cleaning today can save hours in the future.

If you're also struggling with a horde of legacy code zombies, I encourage you to try this "code graveyard" approach. It's surprisingly satisfying.

Top comments (0)