The repository is the source of truth
When the git history and the running system can disagree, they eventually will, and the gap between them is where outages live. Push to deploy closes the gap by making one rule absolute: the main branch is what is in production, and the only way to change production is to change the main branch.
What this buys you
Every deploy has a commit. Every commit has an author, a diff, and a review. So when something breaks at two in the morning, the question "what changed" has an answer you can read, not a guess you have to reconstruct. Rolling back is checking out an earlier commit, not archaeology.
Wiring it up
The host watches the branch and builds on every push. A merge to main is a production deploy. A push to any other branch is a preview deploy with its own URL, which means a reviewer can click a link and see the change running before it merges.
git switch -c fix/checkout-rounding
# work, commit
git push -u origin fix/checkout-rounding
# open a pull request, CI runs, a preview URL appears
# merge -> production deploy, automatically
The discipline that makes it safe
Push to deploy is only as safe as the gate in front of main. That is why the branch is protected and the build must pass before merge (see the CI/CD governance guide). The two ideas are halves of the same system: the pipeline decides what is allowed to ship, and push to deploy makes shipping the default rather than a separate, forgettable step.
When you outgrow the simple case
Long running migrations and feature flags are the two places where "merge equals live" needs care. Gate risky changes behind a flag so the deploy and the release are separate events, and run schema migrations as their own reviewed step. The branch stays the source of truth; you just give yourself a switch to turn things on after the code is already safely deployed.
