A Git Workflow That Scales From Solo to Small Team
Branches, pull requests, and a clean history — a practical workflow you can adopt today and grow into without rework.
Most Git pain isn't about commands — it's about the absence of a workflow. Without one, main becomes a junk drawer, history is unreadable, and every merge is a gamble. This guide gives you one workflow that works alone today and survives your first teammates tomorrow, with no rework in between.
The core rule: main is always deployable
Treat your main branch as sacred: it should always be in a working, deployable state. Everything else follows from defending that rule. You never commit half-finished work directly to main — not because a tool forbids it, but because the moment main can be broken, you lose the one branch everyone trusts.
The loop: branch, commit, pull request, merge
Every unit of work — a feature, a fix — follows the same cycle:
- Branch off main.
git switch -c fix/login-redirect. The name says the type and the intent. Short-lived branches are the goal; a branch that lives for weeks will drift painfully frommain. - Commit in small, meaningful steps. A commit should be one logical change with a message that explains why, not what (the diff already shows what). "Fix redirect loop when session expires" beats "update auth.ts."
- Open a pull request. Even solo. The PR is where you review your own diff with fresh eyes, where CI runs your tests, and — with a team — where a second person catches what you can't see. The PR, not the commit, is the real unit of collaboration.
- Merge, then delete the branch. Once it's reviewed and green, merge to
mainand delete the branch. Done work shouldn't linger as clutter.
This loop is identical whether you're alone or on a team of five. That's the point: adopt it solo and onboarding a teammate changes nothing about how you work.
Writing commit messages your future self will thank you for
A good message has a short imperative subject line (under ~50 characters) and, when the change is non-obvious, a body explaining the reasoning:
Fix redirect loop when session expires
The middleware redirected to /login, but /login itself required a
session, creating a loop. Allow /login through the auth guard.
Six months from now, git log becomes a narrative of why the code is the way it is, not a wall of "wip" and "fix stuff." This is the highest-return habit in this entire guide.
Keeping history clean: merge vs rebase
You'll hear religious wars about this. The practical version:
- Rebase your own feature branch onto the latest
mainbefore merging, to keep its history linear and free of noise commits.git rebase mainwhile on your branch. - Never rebase a branch others are working on. Rebasing rewrites history; doing it to shared commits hands your teammates a mess. The rule of thumb: rebase local, merge public.
- Don't force-push to
main, ever.--force-with-leaseon your own feature branch is fine; force-pushing shared history is how teams lose work.
If this feels like a lot, collapse it to one habit: rebase your feature branch before opening the PR, merge the PR, move on.
Recovering from mistakes without panic
The reason to trust this workflow is that Git almost never truly loses work:
- Committed something wrong?
git revertmakes a new commit that undoes it — safe on shared branches because it doesn't rewrite history. - Reset too far and "lost" commits?
git reflogshows where every branch pointer has been; your commits are almost certainly still there, recoverable by hash. - On the wrong branch?
git stashparks your changes, switch,git stash pop.
Knowing these three turns "I broke everything" into "I'll fix that in ten seconds," which is the calm that makes the whole workflow sustainable.
Why this scales
The workflow doesn't get more complex as the team grows — it gets more valuable, because the same PR step that was self-review becomes peer review, and the same clean history that helped you remember helps the whole team understand. You don't graduate to a "real" workflow later. This is the real one; you just start using its collaboration features when collaborators arrive.
You can move on when branch → commit → PR → merge is automatic, your commit messages explain why, and
git refloghas rescued you at least once.