Production is broken and main has moved on - it contains three half-finished features that cannot ship today. The hotfix question is how to patch what is live without dragging main along. The answer is short: branch from the tag that is running, fix there, tag, deploy, merge back.
The walkthrough#
git switch -c hotfix/invoice-total-rounding v1.14.0
# fix the one thing, with a test
git tag -a v1.14.1 -m "v1.14.1"
git push origin hotfix/invoice-total-rounding v1.14.1
Deploy v1.14.1 exactly the way you deploy everything else - Deploy With Tags, Not Branches applies even more under pressure, because “what is running” must have one unambiguous answer during an incident.
Then bring the fix home so the next regular release does not reintroduce the bug:
git switch main
git merge hotfix/invoice-total-rounding
Discipline under pressure#
The rules that keep a hotfix small:
- One fix. A hotfix branch is not a vehicle for the cleanup you noticed on the way in. Everything else goes into a normal PR tomorrow.
- The test comes too. If the bug was reachable once, it is reachable again; the test is what makes “fixed” verifiable rather than hoped. This is the moment the first CI pipeline earns its keep - the hotfix PR gets the same green check as everything else.
- No shortcuts around review. One approval, even a two-minute one, catches the mistake made at speed. Branch protection should have no “except hotfixes” hole; it should have a fast path through the normal gate.
If the fix is bigger than a hotfix#
When the honest assessment is “this needs a day of work,” stop calling it a hotfix and decide rollback or roll-forward instead. A rollback buys the day cleanly. The worst outcome is the middle path: an ever-growing hotfix branch that is secretly a release, deployed with none of the care a release gets.
Branch from the tag, fix one thing, tag, merge back. Written down and rehearsed once, the next production bug is a procedure, not an event.
Share this post
Keep reading
A First CI Pipeline for a Laravel Project
Install, lint, test, build - four jobs that run on every pull request and turn 'works on my machine' into a check everyone can see.
A Staging Environment Worth Having
Staging only catches what it shares with production. Same deploy path, same services, sanitized data - and a clear rule for what it is for.
Branch Naming Conventions That Scale Past Three People
Branch names are a user interface for your team's work. The conventions that survive growth, the ones that collapse, and why boring always wins.