The Hook (The "Byte-Sized" Intro)
There's one rule that separates competent Git users from dangerous ones: never rewrite history that others depend on. Every team horror story — force-pushed main, lost sprint work, broken CI — traces back to violating this rule. These 5 rules take 2 minutes to memorize and save years of pain.
📖 What are Safe History Rules?
These are guidelines that determine when it's safe to rewrite Git history and when it's not. Following them prevents data loss and team disruption.
Conceptual Clarity
The 5 golden rules:
| # | Rule | Why |
|---|---|---|
| 1 | Only rewrite unpushed commits | Pushed commits are shared property |
| 2 | Never force-push to main/develop | Breaks everyone's clone |
| 3 | Use --force-with-lease instead of --force | Checks for others' work before overwriting |
| 4 | Create a backup branch before risky operations | Cheap insurance |
| 5 | Use revert on shared branches, reset on local | Additive changes are always safe |
The safety spectrum:
| Operation | Risk Level | Safe On Shared? |
|---|---|---|
git revert | 🟢 None | ✅ Always |
git cherry-pick | 🟢 None | ✅ Always |
git commit --amend | 🟡 Low | ❌ Only before push |
git rebase | 🟠 Medium | ❌ Only personal branches |
git reset --soft/mixed | 🟠 Medium | ❌ Only before push |
git reset --hard | 🔴 High | ❌ Only before push |
git push --force | 🔴 Critical | ❌ Never on shared |
Real-Life Analogy
Safe history rules are like firearm safety rules: always treat history as shared (loaded), never point --force at a shared branch (someone), and always create a backup (safety) before operating.
Visual Architecture
Why It Matters
- Team trust: Following these rules means no one ever loses work because of you.
- Branch protection: Many companies enforce these rules via branch protection settings.
- Career: Force-pushing to
mainis a widely-known anti-pattern, tested in interviews. - Recovery cost: Prevention takes seconds; recovery takes hours.
Code
# ─── Rule 1: Only rewrite unpushed commits ───
git log --oneline origin/main..main # Shows unpushed commits
# If empty → nothing is unpushed → safe to rewrite
# ─── Rule 3: Use --force-with-lease ───
git push --force-with-lease origin feature/login
# Checks if remote has new commits you don't have
# Refuses to push if someone else pushed in the meantime
# ─── Rule 4: Backup branch before risky ops ───
git branch backup-before-rebase
git rebase -i HEAD~5
# If something goes wrong:
git reset --hard backup-before-rebase
# ─── Rule 5: Revert on shared, reset on local ───
# Shared branch (main):
git revert abc1234
# Local branch (not pushed):
git reset --soft HEAD~1Key Takeaways
- Never rewrite pushed commits on shared branches — use
revertinstead. - Always use
--force-with-leaseinstead of bare--force. - Create a backup branch before rebasing or resetting.
- Learn the safety spectrum — know which operations are safe where.
Interview Prep
-
Q: What is
--force-with-leaseand why is it safer than--force? A:--force-with-leaseoverwrites the remote branch only if it matches your expected state. If someone else pushed commits you don't have, it refuses to push — preventing you from accidentally deleting their work.--forceoverwrites unconditionally. -
Q: How would you undo a commit on a shared branch? A: Use
git revert <sha>. This creates a new commit that undoes the changes without rewriting history. Never usegit reseton shared branches because it would require force-pushing, which breaks other developers' clones. -
Q: What precaution should you take before an interactive rebase? A: Create a backup branch first:
git branch backup-before-rebase. If the rebase goes wrong, you can restore your branch withgit reset --hard backup-before-rebase. This is cheap insurance against mistakes.