commit
repository
git

How do I revert a Git repository to a previous commit?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Reverting to a previous commit in Git can mean very different operations, and using the wrong one can disrupt collaborators or destroy local work. Some commands preserve history, while others rewrite branch pointers. The correct choice depends on whether the branch is shared and whether you want to keep existing commits visible.

Choose the Right Undo Strategy First

Before running any undo command, define your intent clearly.

  • Undo bad changes on a shared branch while keeping history intact.
  • Remove local unpublished commits from your branch tip.
  • Inspect old code state without changing branch history.

Once intent is clear, command choice becomes straightforward.

Use git revert for Shared Branch Safety

git revert is usually the safest approach for shared branches. It creates a new commit that reverses the target commit patch, so existing history remains stable for everyone.

bash
git log --oneline -n 10
git revert 9ab13ef

This avoids branch pointer rewrites and works cleanly with pull requests, CI traces, and release audit trails.

If you need to revert a range of commits as one change set:

bash
git revert --no-commit 8ac2d10..9ab13ef
git commit -m "Revert unstable checkout pipeline changes"

This is useful when rollback should be documented as one operational action.

Use git reset for Local Unpublished History

git reset moves branch HEAD and is appropriate when commits are local and not shared.

Soft reset keeps changes staged:

bash
git reset --soft HEAD~1

Mixed reset keeps changes in working tree but unstaged:

bash
git reset --mixed HEAD~1

Hard reset discards staged and working tree changes and moves branch to target commit:

bash
git reset --hard 8ac2d10

Hard reset is destructive. Use it only when discarded changes are truly disposable or already backed up.

Inspect Older Commits Without Undoing Anything

Sometimes you only need to build or debug at an old commit. Use detached HEAD so branch tips remain unchanged.

bash
git switch --detach 8ac2d10

Run your tests or inspection commands, then return to your branch.

bash
git switch main

This is the right tool for forensic debugging when no rollback is needed.

Recover Mistakes with Reflog

If you reset or checkout incorrectly, reflog often provides a fast recovery path because it records branch tip history locally.

bash
git reflog --date=local -n 20
git branch recovery/before-reset HEAD@{4}

After validating the rescue branch, you can restore branch tip if required.

bash
git reset --hard HEAD@{4}

Creating a temporary recovery branch first reduces risk while you inspect the intended restore point.

Handle Remote Divergence After Rewriting

If you rewrote local history and must update remote, push with lease protection.

bash
git push --force-with-lease origin main

Lease protection prevents silent overwrite when remote moved since your last fetch. If your branch is protected or shared broadly, prefer revert commits instead of force pushing rewritten history.

Practical Playbooks

Use the following patterns as operational defaults.

  • Shared branch rollback: git revert.
  • Local typo fix in latest commit: git reset --mixed HEAD~1 and recommit.
  • Private branch cleanup before first push: git reset modes as needed.
  • Old-state debugging: detached HEAD checkout.

Having a standard playbook helps teams avoid high-risk ad hoc undo commands during incidents.

Common Pitfalls

  • Using git reset --hard on shared branches and breaking teammate history.
  • Confusing revert and reset, then getting unexpected commit graphs.
  • Force pushing without lease protection and overwriting unseen remote work.
  • Running destructive commands without git status and git log pre-checks.
  • Forgetting reflog exists and assuming mistakes are unrecoverable.

Summary

  • 'git revert is the safe default for shared branch rollback.'
  • 'git reset is for local unpublished history rewriting.'
  • Detached HEAD is for historical inspection without mutation.
  • Use reflog and rescue branches to recover from undo mistakes.
  • Prefer --force-with-lease over plain force when rewritten history must be pushed.
  • Match undo method to collaboration model before running commands.

Course illustration
Course illustration

All Rights Reserved.