Repository Hygiene for Distributed Infra Teams

In a distributed team, the Git repo is the communication backbone. It's how engineers across time zones hand work off to each other, understand what changed and why, and recover when things go wrong. When the repo is messy, all of that breaks down. I've inherited a few repos over the years where the commit history read like a stream of consciousness — "fix", "wip", "fix 2", "please work", "ok actually this" — and debugging an incident in those conditions is genuinely painful. You can't tell what changed, when, or why. You're just grep-ing and hoping.

The policies below aren't about being pedantic. They're about making the repo useful as a communication tool rather than just a storage bin.

Main is Sacred

main must always be deployable. Not "usually deployable" or "deployable after we fix the one thing." Always. If main is broken, the entire team is blocked — and in a distributed team, that means people in other time zones are blocked for hours before anyone in your timezone wakes up.

No direct commits to main. Everything comes through a pull request. We use squash-and-merge, which gives us one clean commit per feature on the main branch history rather than a detailed play-by-play of every intermediate state. Automated checks — linting, unit tests, security scans — must pass before merge. These aren't optional. The moment you start making exceptions is the moment the guarantees go away.

Commit Messages That Actually Help

A commit message is a note to whoever is debugging your code at 3 AM six months from now. Which might be you.

Post this

A commit message is a note to whoever is debugging your code at 3 AM six months from now, which might be you. The format matters.

I enforce Conventional Commitsfeat: for new capabilities, fix: for bug repairs, chore: for maintenance. Beyond the obvious benefit of knowing what kind of change you're looking at, this format lets you automate changelog generation and semantic versioning, which is legitimately useful and saves real time.

The body of a commit message is where most people skip too much. A one-line subject is fine for obvious changes. For anything with context — a non-obvious fix, a deliberate tradeoff, a workaround for something broken upstream — write the body. Explain why, not what. The diff already shows what changed. Future readers need to know why you made that choice.

Fixing History (When You Have To)

Sometimes things go sideways. Someone commits a secret. Someone force-pushes to the wrong branch. Knowing how to surgically fix history is a required skill for senior engineers on infra teams — and it's worth practicing before you need it in an emergency.

If a feature branch has diverged too far or contains something that shouldn't be there, resetting to main and replaying valid changes is often the cleanest approach:

# Backup current state just in case
git branch feat-backup

# Reset local branch to match remote main
git fetch origin
git reset --hard origin/main

Occasionally, for audit or migration purposes, you need to backdate a commit — importing legacy code while preserving original dates, for example. Git allows this via environment variables:

GIT_AUTHOR_DATE="2023-01-01 12:00:00 +0000" \
GIT_COMMITTER_DATE="2023-01-01 12:00:00 +0000" \
git commit -m "Import legacy module"

Use this sparingly. Manipulating history in shared branches is a fast way to lose team trust.

Tooling as Guardrails

Policies that depend on willpower don't hold up. Tooling that enforces behavior automatically does.

Pre-commit hooks run formatters before code leaves the developer's machine — prettier, black, gofmt, whatever's appropriate for the stack. Developers stop thinking about formatting because it just happens. Husky enforces commit message standards so "wip" and "fix 2" can't make it into the history. CODEOWNERS automatically routes reviews to the right people — security team for IAM changes, database team for schema migrations, whoever owns the relevant domain. Nobody has to remember who to tag.

The goal is that doing the right thing should be easier than doing the wrong thing. If your process requires engineers to remember to do five things manually before every commit, some of those things will get forgotten. Automate them.

Onboarding and the Repo as Documentation

A clean repository speeds up onboarding significantly. When a new engineer joins a distributed team, the repo history is one of the first things they use to understand how decisions got made and why the codebase looks the way it does. A history full of meaningful commits tells a story. A history full of "fix" and "asdf" and "trying something" tells nothing.

Treat the git history with the same care you'd give your production database. It's an asset, and how you maintain it reflects on the discipline of the team.

← Back to Home