Git Good
Git Good
Git Good
The Solo Developer: Nobody Is Watching
S1 E211m · Apr 12, 2026
A solo developer at midnight commits code with a message typed in two seconds—Git init, add, commit, push—five commands between them and losing everything they built.

The Solo Developer: Nobody Is Watching

The Five Commands

This is episode two of Git Good, Season Two.

There is a developer somewhere right now, working alone, at midnight or two in the afternoon, it does not matter because nobody is keeping track. They have a project. Maybe it is an app they have been tinkering with for three years. Maybe it is a script that automates something at work that their boss does not know about. Maybe it is a game, half finished, that they will probably never release. And they use Git. They use exactly five commands.

Git init, once, at the beginning. Git add, usually with a dot, because selecting individual files feels like a formality when you are the only person who will ever look at this. Git commit, with a message they type in about two seconds. Git push, to get it off their machine and onto a server somewhere. And when something goes wrong, which it does, git pull, or maybe just deleting the local copy and cloning again from scratch. Init, add, commit, push, and in emergencies, start over. That is Git for most solo developers. Not a workflow. Not a branching strategy. A save button with extra steps.

One developer on Reddit put it simply. If someone took Git away from me, I might need some professional help. Not because of the branching or the history navigation or any of the features that tutorials spend hours explaining. Because it is the thing between them and losing everything. Git for the solo developer is not a collaboration tool. It is a safety net strung across a canyon they have fallen into before.

The Wasteland

If the five commands are the workflow, the commit messages are the evidence. Open git log on any solo developer's private repository and you will find a landscape so barren it could qualify as modern poetry. "Fix." "Stuff." "Changes." "WIP." "Asdfgh." "Update." The word "update" appearing fourteen times in a row, each one representing a completely different set of changes that the developer will never be able to distinguish again.

There is a particular subspecies of bad commit message that deserves its own taxonomy. There is the surrender message: "I give up trying to fix this tonight." There is the triumph message: "holy crap it actually works." There is the existential message, which is usually just a period. There is the negotiation message: "please work this time." And there is the panic message, which is a string of characters that suggests the developer was typing so fast they forgot they were talking to a computer and not praying.

A developer who goes by the name HotfixHero cataloged what they called the six worst commit messages they saw in one week. The list included "fixed it," which tells you nothing about what was broken. "Changes," which describes every commit in the history of every repository. And the classic "stuff," which manages to convey less information than writing nothing at all.

But here is the thing nobody says out loud. When you are the only person who will ever read the log, who are you writing the message for? The textbook answer is "your future self." The honest answer is nobody. Three months from now you will not look at git log to understand what changed. You will look at the code. Or you will not look at anything, because the project will be abandoned like every other side project, sitting in a GitHub repository with eleven commits and a README that says "TODO: add README."

The commit message wasteland is not laziness. It is rational behavior. The cost of writing a good commit message is thirty seconds of thought. The benefit, for a solo developer, is almost zero. The only time it would matter is during a crisis, and during a crisis you will not be reading commit messages anyway. You will be googling "how to undo last commit" and ending up on Stack Overflow like everyone else.

The Accidental Inventor

There was a developer, mentioned in a thread that circulated through several communities, who took the commit message problem in an unexpected direction. They used a specific string in their commit messages as a deployment trigger. The string was "q!" which, for anyone who has used the text editor Vim, is the command to quit without saving. This developer had wired up a system where any commit message containing "q!" would trigger their deployment pipeline. Push a commit with that magic string, and the code goes live.

This is absurd and also quietly brilliant. They had, without knowing the terminology, reinvented the concept of tagged releases. In a proper Git workflow, you tag a specific commit as a release candidate, and your deployment system watches for tags. This developer did the same thing with a string that normally means "throw this away." They had independently discovered that Git's commit metadata can carry signals beyond its literal content, and they had done it in the most chaotic way imaginable.

The story is funny, but it reveals something important. Solo developers do not read documentation about Git workflows. They do not attend talks about branching strategies. They build systems out of whatever they understand, and what they understand is: I type a message, I push, something happens on the other end. If the deployment system needs a signal, the commit message is the only channel they know. So the commit message becomes the signal. It is not how Git was designed to work. But Git was not designed for someone working alone at two in the morning with a deployment pipeline held together by string.

Branching in an Empty Room

One of the earliest things every Git tutorial teaches is branching. Create a branch for your feature. Work on it in isolation. Merge it back when it is done. This makes perfect sense when other people are working on the same codebase. You do not want your half-finished feature interfering with their work. Branches keep parallel efforts from colliding.

But what happens when there is no parallel effort? When you are the only person touching the code? Branching becomes a conversation with yourself. You create a branch, work on it, and merge it back. Nobody reviewed it. Nobody needed to be protected from your changes. The branch existed for an audience of zero. It is like setting the table for dinner when you live alone. You could eat standing over the sink, and nobody would know.

Git is not just about collaboration. Even as a solo developer, I use stash, bisect, and worktree regularly. The tools are designed for managing complexity, and complexity does not care whether one person or fifty created it.

Mikkel Paulson, a developer who wrote about using Git seriously even while working alone, makes the case that branches have value beyond coordination. They let you park an experiment without losing it. They let you switch contexts between a bug fix and a feature without tangling the two together. They give you a clean separation between what works and what you are still figuring out. These are real benefits. But they require a level of Git literacy that most solo developers do not have and do not feel motivated to acquire. The five commands work. Adding branches means adding mental overhead. And when the only person who benefits is you, the overhead rarely feels worth it.

So most solo developers commit directly to main. Every change, every experiment, every half-baked idea, all on one branch. It works fine right up until it does not. And when it does not, when something breaks and you need to go back to a version from last Tuesday, you discover the real reason solo developers should care about Git.

The Undo Button

The killer feature of Git for someone working alone is not branching. It is not collaboration. It is not the elegant content-addressed storage or the directed acyclic graph of commits. It is the undo button. The ability to go back.

One developer described it in a way that stuck. It is like saving a game where you might suddenly die. You do not save because the game asks you to. You save because you have learned, through painful experience, that the next room might contain something that destroys three hours of progress. Every commit is a save point. Not a carefully curated snapshot of a meaningful milestone. A save point. A moment in time you can return to when the present catches fire.

This is the value proposition that no Git tutorial leads with, and it is the one that actually matters to most people. Not "track your changes so your team can review them." Not "create branches so you can work on features in parallel." Just: if you break something, you can go back. If your computer dies, the code is somewhere else. If you accidentally delete a file, it is recoverable. Git is insurance. Boring, invisible, essential insurance. And like real insurance, you do not appreciate it until you need it and it is not there.

The irony is that the undo button is also the feature that Git makes hardest to use. The last episode talked about the wall, the hostile vocabulary and confusing error messages. That wall is at its most punishing exactly when the undo button matters most: during a crisis. You need to go back to last Tuesday's version. You know Git can do this. But do you use reset? Checkout? Revert? Restore? Each does something different, some of them destructively, and the names give you no clue which one you want. So you Google it, and you find five different answers, each assuming a different starting state. The tool that is supposed to save you requires you to understand it precisely at the moment you are least capable of understanding anything.

The Invisible User

There is a new kind of solo developer. They do not know five commands. They do not know any commands. They have never opened a terminal, never typed git anything, never seen a commit message. And yet they have repositories. They have commit histories. They have code on GitHub. The code works, mostly, and it got there without them ever interacting with Git directly.

They are called vibe coders. The term comes from Andrej Karpathy, who used it in early two thousand twenty-five to describe a way of building software where you describe what you want in plain language and an AI writes the code. You do not read the code. You do not debug the code. You see what it does, and if it does not do what you want, you describe the problem again and the AI tries a different approach.

I asked vibe coders whether they use Git. The top answers were no and not really. They do not discuss version control. It is the dog that did not bark.

Jason Liu, a developer who writes about AI tooling, noticed this silence. He looked at vibe coding communities and found that Git was almost entirely absent from the conversation. Not rejected. Not debated. Just missing. The AI tools handle version control the way they handle everything else: automatically, invisibly, without asking. Cursor, one of the most popular AI coding environments, commits on behalf of the user. The messages are generated. The timing is arbitrary. The commit history of a vibe-coded project is not a record of human decisions. It is a log of machine iterations, each one a slight variation on the last, with messages like "Update" and "Fix" and "Patch" that sound exactly like the commit message wasteland from traditional solo developers. Except the traditional developer chose to write "stuff." The vibe coder never wrote anything at all.

This matters because Git's entire model assumes a human author. The commit has a name and an email attached to it. The message is supposed to explain intent. The diff shows what changed. But when the code is generated by a machine, guided by vague descriptions from a person who never reads the output, every field in that commit is fiction. The author did not write the code. The message does not reflect a decision. The diff is not a change someone made. It is a change an algorithm made, rubber-stamped by someone who was looking at the result, not the process. A later episode this season will dig into what this means for trust, attribution, and the fundamental model that Git was built on. For now, just notice the contrast. The five-commands developer learned a little and uses it clumsily. The vibe coder learned nothing and it works anyway. Both end up with the same commit history: a wall of "update," "fix," "stuff." One typed those words. The other never even saw them.

A Forge of Your Own

There is a third kind of solo developer who took a different path entirely. They decided that their code does not belong on someone else's server. Not on GitHub, not on GitLab, not on any platform that could change its terms, get acquired, or decide that their private repositories are training data for a large language model. They run their own Git server. And in two thousand twenty-five, that got remarkably easy.

Forgejo is a self-hosted Git platform that forked from Gitea in two thousand twenty-two after disagreements about corporate governance. The name comes from the Esperanto word for forge. It is lightweight enough to run on a Raspberry Pi, needs about four hundred megabytes of memory at idle, and gives you everything GitHub gives you except the network effect: repositories, issues, pull requests, even CI runners that are compatible with GitHub Actions workflows.

Installing and running Forgejo has been a very pleasant experience so far. I have it running on a small container, and I am using it for documentation rather than code. It works well even under unexpected traffic.

Neil Brown, a blogger and self-hoster, wrote about his experience running a personal Forgejo instance in September two thousand twenty-five. He keeps it on a small Proxmox container. He uses it not for code but for documentation, pushing markdown files from his terminal. It handles everything he needs and nothing he does not.

But the story that captured something deeper came from a thread about a parent who set up a Forgejo instance at home so their ten-year-old could learn Git. Not GitHub, with its social features and public profiles and contribution graphs and all the pressure that comes with putting your work in front of the world. A private forge, on a home server, where a child could make mistakes without an audience. Could commit with terrible messages and experiment with branches and break things and fix them in complete privacy. The way you learn best: alone, safe, and free to fail.

That image, a child's first git push landing on a server in their own house, captures something that gets lost in all the talk about workflows and collaboration and platform monopolies. Git started as a tool for one person's problem. Linus needed to track the kernel. The power of Git was always that every clone is complete, every copy is self-sufficient, every developer is sovereign. The solo developer, working alone, with nobody watching, is not a reduced version of the Git experience. They are the original version. Everything else, the pull requests, the code reviews, the branch protection rules, those came later. The five commands came first. And for most people, the five commands are still enough.

That was episode two of Git Good, Season Two.

Git stash. The solo developer's secret weapon. You are in the middle of something, half-finished, not ready to commit, and suddenly you need to fix a bug on main or just try a completely different approach. Git stash takes your uncommitted changes and hides them. Your working directory goes back to clean. Fix the bug, push the fix, then git stash pop and your half-finished work reappears exactly where you left it. Think of it as a pocket dimension for code you are not ready to talk about yet. You can stash multiple times, list your stashes, even name them. Most solo developers do not know it exists, which is a shame, because it solves the exact problem they keep solving by copying files to a folder called backup-do-not-delete on their desktop.