{"post":{"slug":"how-to-undo-a-git-commit-2026","title":"How to undo a git commit in 2026","excerpt":"Git gives you multiple ways to undo a commit depending on whether the commit is local or already pushed. Choosing the right command prevents data loss and history rewrites.","category":"code","date":"April 19, 2026","author":"ByteLedger Team","content":"<span class=\"dropcap\">U</span>ndoing a git commit is one of the most Googled Git questions, yet the answer is usually different depending on one key fact: has the commit been pushed to a shared branch? The local vs. remote distinction determines whether you can rewrite history or must add a new commit that reverses the change.\n\n## What changed in 2026\n\n- **`git revert` is the team-safe standard** — nothing has changed here; it has always been the right choice for shared branches.\n- **`git restore` replaced `git checkout -- file`** for unstaging and discarding file changes — cleaner API, same effect.\n- **Branch protection rules on GitHub/GitLab now default to blocking force-push on main** — if you need to undo something on main, revert is usually your only option.\n- **AI-assisted commit messages** mean commits are more descriptive, making `git log --oneline` easier to navigate when looking for the commit to undo.\n\n## The decision tree\n\n```\nDid you push the commit to a shared branch?\n├─ YES → git revert <sha>   (safe, adds a new commit)\n└─ NO\n   ├─ Keep the changes, just undo the commit?\n   │  └─ git reset --soft HEAD~1\n   ├─ Unstage the changes too (keep in working tree)?\n   │  └─ git reset --mixed HEAD~1   (default)\n   └─ Discard everything?\n      └─ git reset --hard HEAD~1\n```\n\n## git revert — safe for shared branches\n\n```bash\n# Undo a specific commit by SHA\ngit revert abc1234\n\n# Undo the last commit\ngit revert HEAD\n\n# Undo multiple commits (creates one revert commit per target)\ngit revert HEAD~3..HEAD\n\n# Revert but do not auto-commit (stage the changes for review first)\ngit revert --no-commit abc1234\ngit diff --cached   # review\ngit commit -m \"Revert feature X\"\n```\n\n`git revert` is a forward operation — it adds a new commit that applies the inverse of the target commit. History is preserved; no force-push needed.\n\n## git reset — local branches only\n\n```bash\n# --soft: move HEAD back, keep changes staged\ngit reset --soft HEAD~1\n# Use this to re-commit with a different message or split into two commits\n\n# --mixed (default): move HEAD back, unstage changes, keep in working tree\ngit reset HEAD~1\n# Use this to re-stage selectively or discard specific files\n\n# --hard: move HEAD back, discard all changes in index and working tree\ngit reset --hard HEAD~1\n# DESTRUCTIVE — make sure you have no unsaved work\n```\n\n| Flag | HEAD | Index (staged) | Working tree |\n| --- | --- | --- | --- |\n| --soft | moved back | unchanged | unchanged |\n| --mixed | moved back | reset | unchanged |\n| --hard | moved back | reset | reset (discarded) |\n\n## Amend the last commit (before pushing)\n\n```bash\n# Fix the commit message only\ngit commit --amend -m \"Better commit message\"\n\n# Add a forgotten file to the last commit\ngit add forgotten-file.ts\ngit commit --amend --no-edit\n```\n\n`--amend` rewrites the last commit. Use it only on local commits — amending a pushed commit requires a force-push.\n\n## Recover with git reflog\n\nEvery movement of HEAD is recorded in the reflog for ~90 days. If you ran `git reset --hard` and lost commits:\n\n```bash\ngit reflog\n# HEAD@{0}: reset: moving to HEAD~1\n# HEAD@{1}: commit: add feature X    <-- this is the lost commit\n# HEAD@{2}: commit: fix bug Y\n\n# Recover\ngit checkout -b recovery-branch HEAD@{1}\n# or\ngit reset --hard HEAD@{1}\n```\n\nThe reflog is local — it does not sync to the remote. If your teammate pushed the commit but you have not pulled it, `git fetch` and look at the remote ref.\n\n## Undo a pushed commit (force-push on your own branch)\n\n```bash\n# Only acceptable on branches you own and no one else is working on\ngit reset --hard HEAD~1\ngit push --force-with-lease origin feature/my-branch\n```\n\n`--force-with-lease` is safer than `--force` — it fails if someone else pushed to the branch since your last fetch, preventing you from overwriting their work.\n\n**Never force-push to main, master, or any shared branch.**\n\n## Common mistakes\n\n**`git reset --hard` with uncommitted changes in the working tree.** The reset discards both the commit *and* any unstaged changes. Check `git status` first and stash if needed.\n\n**Reverting a merge commit without `-m`.** Merge commits have two parents. `git revert <merge-sha>` requires `-m 1` (or `-m 2`) to specify which parent to revert to.\n\n**`git push --force` instead of `--force-with-lease`.** `--force` overwrites unconditionally; `--force-with-lease` is a safety check. Always prefer `--force-with-lease`.\n\n**Amending a commit that has already been pushed.** It creates a diverged history that requires a force-push and breaks colleagues' local branches.\n\n## What to skip\n\n- **`git checkout HEAD~1`** to \"undo\" a commit — this puts you in detached HEAD state, not a branch. Use `reset` or `revert`.\n- **Deleting the `.git` folder** to \"start fresh\" — you lose all history. If the repo is broken, ask for help.\n- **Force-pushing to main** — on most platforms this is blocked by default for good reason; use `git revert`.\n\n## FAQ\n\n**What is the difference between revert and reset?**\n`revert` adds a new commit that undoes the change — history is preserved and the operation is safe for shared branches. `reset` moves the branch pointer backward, rewriting history — only safe for local, unpushed commits.\n\n**Can I undo a git revert?**\nYes — `git revert <revert-sha>` reverts the revert, restoring the original change.\n\n**How do I undo all commits since I branched from main?**\n`git reset --soft $(git merge-base HEAD main)` moves HEAD back to the branch point and keeps all changes staged, ready to re-commit.\n\n**Is it safe to amend a commit that has been pushed to a PR branch that only I use?**\nTechnically yes, with `--force-with-lease`. Be explicit with your team that you rewrote history, because their local branch will diverge.\n\n## Where to go next\n\n- [How to squash commits in 2026](/blog/how-to-squash-commits-2026)\n- [How to fix a merge conflict in 2026](/blog/how-to-fix-a-merge-conflict-2026)\n- [How to set up pre-commit hooks in 2026](/blog/how-to-set-up-pre-commit-hooks-2026)","hue":321,"metaTitle":"How to Undo a Git Commit in 2026: reset, revert, reflog","metaDescription":"Step-by-step guide to undoing git commits in 2026. Covers git revert, git reset --soft/--mixed/--hard, git reflog, and when force-push is acceptable.","keywords":["how to undo a git commit 2026","git revert commit","git reset soft mixed hard","undo last git commit","git reflog recover commit","git undo pushed commit","git reset head~1","git amend commit 2026","undo git commit without losing changes","git history rewrite 2026"],"tldr":["**git revert creates a new commit that undoes the target** — safe for shared branches because it does not rewrite history.","**git reset moves the branch pointer backward** — use --soft to keep changes staged, --mixed to unstage, --hard to discard entirely.","**Never force-push to main/master** — if a bad commit reached the shared branch, use revert.","**git reflog is your safety net** — every HEAD move is logged; you can recover from almost any mistake within 90 days.","**Skip:** git reset --hard without checking git status first — you will silently discard uncommitted work along with the commit."],"readTime":"5 min read","wordCount":1003},"related":[{"slug":"how-to-write-a-good-commit-message-2026","title":"How to Write a Good Commit Message in 2026: a practical guide","excerpt":"A good commit message explains why a change was made, not just what changed. Here is a simple, durable format and the habits that make a git history actually useful months later.","category":"code","date":"June 16, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":205},{"slug":"how-to-write-good-commit-messages-2026","title":"How to write good commit messages in 2026: the standard that sticks","excerpt":"A good commit message is a letter to the next engineer who has to understand why this code exists. This 2026 guide gives the rules and the template.","category":"code","date":"April 6, 2026","author":"ByteLedger Team","readTime":"6 min read","hue":312},{"slug":"how-to-factory-reset-a-phone-2026","title":"How to factory reset a phone in 2026: Android and iPhone, safely","excerpt":"A factory reset done wrong leaves data exposed or leaves the phone locked. Here is the safe, complete 2026 process for both Android and iPhone.","category":"tech","date":"March 30, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":248}],"sameCategory":[{"slug":"bazel-build-explained-2026","title":"Bazel Explained: What Hermetic Builds Actually Cost","excerpt":"Bazel delivers reproducible, precisely cached builds and demands that you describe everything. Here is what you get, what it costs, and who should say no.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":145},{"slug":"graphql-federation-2026","title":"GraphQL Federation: One Graph, Many Teams","excerpt":"Federation composes independently-owned subgraphs into a single API. Here is what it solves, the operational cost it adds, and when a simpler gateway is enough.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":300},{"slug":"hermetic-builds-explained-2026","title":"Hermetic Builds Explained: Same Inputs, Same Output","excerpt":"A hermetic build depends only on declared inputs. Here is what that property gives you, the common leaks that break it, and how to move toward it incrementally.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":130},{"slug":"monorepo-tooling-compared-2026","title":"Monorepo Tooling Compared: What You Actually Need","excerpt":"Monorepo tools solve task orchestration and caching, not repository layout. Here is what each tier provides and how to tell when you have outgrown the simple option.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":150}],"newer":{"slug":"how-to-understand-your-credit-report-2026","title":"How to understand your credit report in 2026: read every line without confusion","excerpt":"Your credit report controls your borrowing costs, rental approvals, and sometimes your job prospects. Here is exactly how to read and interpret every section in 2026.","category":"finance","date":"April 19, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":284},"older":{"slug":"how-to-use-ai-for-blog-outlines-2026","title":"How to use AI for blog outlines in 2026: structure, SEO, and speed","excerpt":"AI blog outlines in 2026 compress hours of research into minutes — but only if you treat the AI output as a structured draft to interrogate, not a finished plan to execute blindly.","category":"ai","date":"April 19, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":205}}