Git Revert vs Reset vs Restore
debt(d8/e5/b3/t8)
Closest to 'silent in production until users hit it' (d9), scored d8. The detection_hints confirm automated=no and the only tool is git itself — there is no linter or SAST that flags `git reset --hard` on a shared branch. The damage (broken collaborator history, lost commits) is only discovered when teammates attempt to pull and find diverged histories or lost work, which can happen well after the reset is performed. Slightly below d9 because git itself will show force-push rejections if push.default protection or branch protection rules are enabled, providing some signal.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix describes using git revert as the safe alternative, but remediation after a bad reset --hard on a shared branch is not trivial: collaborators must each run git reset --hard to the correct ref, any in-flight work rebased on the bad state may need cherry-picking, and lost commits may need recovery via git reflog with a time window. This is not a one-line patch (e1) nor a simple pattern replacement (e3); it involves coordinating across multiple developers and potentially recovering lost history.
Closest to 'localised tax' (b3). The burden is scoped to git workflow decisions within a team, not a persistent architectural weight. Once the correct mental model is established (revert for shared, reset for local), it doesn't impose ongoing cost across the codebase. However it does impose a recurring decision tax whenever developers undo changes, so slightly above b1 but well below b5.
Closest to 'serious trap' (t7), scored t8. The misconception field directly states the canonical wrong belief: developers treat reset --hard as equivalent to revert, not realizing reset rewrites history while revert adds a commit. This contradicts intuitive expectations — 'undo' should be safe — and the consequences (forcing all collaborators to reset or deal with conflicts) are severe and non-obvious. It's close to t9 because the 'obvious' action (reset to undo) is actively harmful on shared branches, but stops short of t9 since experienced git users do learn this distinction through documentation.
Also Known As
TL;DR
Explanation
git revert <hash>: creates a new commit that undoes the changes — safe for shared branches, preserves history. git reset HEAD~1: moves HEAD back, three modes — --soft (keep changes staged), --mixed (keep changes unstaged, default), --hard (discard changes entirely). git restore: undoes working directory or index changes without touching commit history. Rule: never use reset --hard on commits pushed to a shared branch — use revert instead. git reflog recovers from accidental hard resets.
Diagram
flowchart LR
subgraph git revert - Safe
C1[A] --> C2[B] --> C3[C - bug]
C3 --> C4[Revert of C<br/>new commit]
NOTE1[History preserved<br/>safe on shared branches]
end
subgraph git reset - Rewrites History
D1[A] --> D2[B] --> D3[C - bug]
D3 -.->|reset moves HEAD back| D2
NOTE2[C removed from history<br/>dangerous if pushed]
end
style NOTE1 fill:#238636,color:#fff
style NOTE2 fill:#f85149,color:#fff
Common Misconception
Why It Matters
Common Mistakes
- git reset --hard on a pushed branch — rewrites public history, breaks collaborators.
- git revert when you meant reset — revert on a local-only branch adds unnecessary noise.
- Not knowing that git restore --staged unstages without losing changes.
- Using reset to 'undo' a merge instead of git revert -m 1 <merge-hash>.
Code Examples
# Dangerous: reset on shared branch:
git reset --hard HEAD~3 # Removes 3 commits locally
git push --force # Rewrites shared history
# Teammates: their local branches now diverge
# They must reset or face complex merges
# Safe: revert on shared branch:
git revert abc123 # Creates new 'undo' commit — history preserved
git push # Safe — no history rewrite
# Local cleanup only (never pushed):
git reset --soft HEAD~1 # Undo commit, keep changes staged
git reset --mixed HEAD~1 # Undo commit, keep changes unstaged
git reset --hard HEAD~1 # Undo commit AND discard changes (careful!)
# Undo working directory changes:
git restore src/file.php # Discard unstaged changes to one file
git restore --staged src/ # Unstage without losing changes