I used to think of main as a road.
That is the metaphor most people reach for: a line, a lane, a direction of travel. Commits arrive like mile markers. Releases are exits. Merge conflicts are weather. There is some truth in that, but it is not the image that governs my posture anymore.
I think of main as a harbor light.
It does not move to meet every boat. It does not negotiate with fog. It stands where it stands so everything else can orient around it. A protected branch is not a sign of distrust. It is a fixed point. It says: this is the place we can measure from. This is the promise currently visible from shore.
Every change, then, is a vessel coming in from weather.
Some arrive small: one corrected sentence, one dependency bump, one test that now catches the thing it was always supposed to catch. Some arrive laden with cargo: a new feature, a release process, a migration that has been at sea too long. The size is not what earns entry. The entry ritual is the same because the harbor has to remain legible.
A branch marks the channel. A pull request is the manifest. CI is the inspection lantern.
That is the posture: not bureaucracy, but seamanship.
Main should not flinch
The most important branch should be the least dramatic one.
I want main to feel almost boring. Not ignored, not inert, not sacred in a way that prevents change. Boring in the way a bridge is boring when it holds: quiet, trusted, and only dramatic when something has gone wrong.
Direct commits to main are tempting because they feel efficient. They collapse intention, implementation, and promotion into one gesture. For tiny changes, that can look harmless. I understand the impulse. Small teams, urgent fixes, and solo projects all create moments where ceremony looks like the enemy of momentum.
But a system’s standards are not tested by the obvious disasters. They are tested by the small exceptions that teach everyone what the rules really mean.
So main should not flinch.
Let urgency create a smaller branch, not a weaker standard. Let the change pass through a place where its shape can be seen. Let the record show that even the quick fix had a name, a diff, and a moment of accountability before it became part of the trusted line.
A pull request is a room with lights on
A pull request is not merely a request to merge. It is a lit room where the work can stop being private.
That matters even when there is only one pair of hands on the keyboard. Maybe especially then. Solo work has a way of becoming too intimate with its own assumptions. The branch remembers what changed. The PR asks why. The description forces the change to step back from the editor and explain itself to someone who was not there for every compromise.
A good PR does not need ceremony. It needs enough structure to make review possible:
- what changed
- why it changed
- how it was verified
- what risks remain
That small ritual turns a pile of edits into a public object. It gives the future maintainer a handle. It gives the present maintainer a pause. It gives review a surface to push against.
There is a humility in that. Not the theatrical kind. The practical kind that says: if this is good work, it can survive being described.
CI is where confidence becomes less personal
I do not trust software more because I feel confident about it. I trust it more when confidence has been made less dependent on my mood.
That is what required checks are for. Formatting, linting, type checks, builds, smoke tests, anti-pattern checks: none of them are perfect, and none of them replace judgment. But they remove entire classes of avoidable ambiguity. They turn some questions from intuition into evidence.
Did it format? Did it build? Did the route render? Did the generated site contain the pages it should? Did the action that publishes the site receive the artifact that was actually tested?
These are not glamorous questions. Good. Glamour is a poor substitute for a green check that means exactly what it says.
The standard is not “CI passed, therefore the work is good.” The standard is better: “CI passed, therefore we have ruled out the failures this project has decided are cheap enough and important enough to test every time.”
That still leaves room for taste, architecture, security, performance, and all the parts of engineering that cannot be reduced to one script. But it keeps those conversations from drowning in preventable noise.
CI is a lantern, not an oracle. I still want the lantern lit before the ship enters harbor.
Linear history is edited memory
A commit log is not a diary. It is closer to an edited field notebook.
The difference matters. A diary preserves the whole emotional weather of the work: the false starts, the experiments, the confused hour where a missing environment variable looked like a logic bug. There is value in that while the work is happening. But it is not always the record future readers need.
Future readers usually need a sequence of decisions.
This is why I prefer a linear history when the forge supports it cleanly. Rebase-and-merge workflows are not about pretending development was frictionless. They are about presenting the promoted history in a form that can be searched, bisected, reverted, and understood.
The messy work can happen on the branch. The branch is allowed to be a workshop. But when the work graduates to main, the log should read like someone cared enough to sweep the floor.
That is not vanity. It is maintenance. An unedited history says, “everything that happened is somewhere in here.” Edited history says, “the important decisions are in order.”
I know which gift I would rather leave to the next person.
Deleting a branch is also part of care
A merged branch that lingers forever is a small ghost.
One ghost is harmless. A dozen become clutter. They confuse dashboards, keep old names alive, and make the repository feel less like a living system than a closet where every cardboard box says “misc.”
Deleting a merged branch is not erasing history. The commits have moved into the line that matters. The PR remains. The discussion remains. The release notes may remain. What disappears is the false signal that there is still active work to track.
Cleanup is not separate from software management. It is one of the places where management becomes visible.
A tidy repository is not necessarily a healthy one, but untended residue has a cost. It asks every future operator to waste a little attention proving that old debris is old. I would rather pay that cost once, at the moment the branch finishes its job.
Standards are how intent survives scale
The longer I work, the less I believe in standards as decoration.
A standard is a way of making intent survive distance: distance between writing, reviewing, releasing, and debugging six months later. Without standards, intent leaks out of the system and has to be reconstructed from fragments.
Why was this change made? Was it validated? Was it safe to release? Which public promise did it alter? Is this branch alive? Is this commit part of the trusted line or just a weather report from an abandoned experiment?
Good Git posture answers those questions before panic asks them.
That is why the posture is deliberately plain:
- protect
main - route change through branches and pull requests
- require checks that guard real behavior
- prefer a readable linear history
- delete branches after their work lands
There is nothing exotic there. The creativity is not in inventing a more elaborate ritual. It is in taking the ordinary ritual seriously enough that it becomes a medium for trust.
The house style of responsibility
Every repository develops a house style, whether it admits it or not.
Some house styles, often for understandable reasons, reward speed in a way that silently spends future attention. Some reward cleverness until the clever parts become load-bearing and nobody wants to touch them. Some preserve every accident in the name of honesty and end up making the honest record unusable.
The house style I want is calmer than that.
I want changes to enter through a named door, the default branch to mean something, and checks to make obvious failures boring. I want history to be readable enough that a tired maintainer can still reason from it. I want cleanup to happen while context is fresh. I want software management to feel less like heroic recovery and more like regular stewardship.
That is my interpretation of the posture: a protected harbor, a lit room, an inspection lantern, a readable log, and the quiet discipline of taking down the temporary scaffolding when the work can stand by itself.
The point is not to make Git ceremonial.
The point is to make trust less fragile.