← Back to DevBytes

Git Revert vs Reset vs Restore

Understanding Git Revert

Git revert creates a brand new commit that undoes the changes introduced by a previous commit. Instead of altering history, it adds a layer on top, preserving the original commit and recording the reversal as a separate event. This makes revert the safest way to "undo" commits that have already been shared with others.

Why Revert Matters

How to Use Git Revert

To revert the most recent commit:

git revert HEAD

This opens an editor for a commit message (usually "Revert <original commit message>"). After saving, a new commit is created that undoes the changes from HEAD.

To revert a specific commit by its hash:

git revert abc123

If the commit you're reverting is a merge commit, you must specify which parent lineage to keep. Use the -m flag followed by the parent number (1 for the mainline, 2 for the merged branch):

git revert -m 1 abc123

For reverting multiple commits without creating a separate revert for each, you can use the --no-commit (or -n) flag to stage the changes and then commit them all at once. This is useful when reverting a range of commits that are consecutive:

git revert --no-commit abc123..def456
git commit -m "Revert range of commits"

Note: the range syntax abc123..def456 is inclusive of def456 but excludes abc123. Adjust accordingly or revert commits individually if needed.

If conflicts occur during a revert, Git will pause and ask you to resolve them. After fixing the conflicts, use:

git add .
git revert --continue

Understanding Git Reset

πŸš€ Deploy your AI agent in 10 minutes

Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.

Try it free →

Git reset moves the current branch pointer to a specified commit, and optionally updates the staging index and working directory. It rewrites history, making it powerful but dangerous when used on branches that have been pushed to a shared repository.

Why Reset Matters

How to Use Git Reset

Reset modes explained:

Undo the last commit but keep changes staged (so you can re-commit with a different message or add more changes):

git reset --soft HEAD~1

Undo the last commit and unstage the changes (they remain as working tree modifications):

git reset HEAD~1

Or explicitly:

git reset --mixed HEAD~1

Completely discard the last commit and all its changes:

git reset --hard HEAD~1

Reset a branch to match a remote state (discard all local commits and changes not yet pushed):

git fetch origin
git reset --hard origin/main

Unstage a specific file (this is a mixed-mode reset on a path, not moving HEAD):

git reset HEAD file.txt

This keeps your working directory changes but removes the file from the staging area.

Important warning: After a reset to a previous commit, if the undone commits were already pushed, you'll need to force-push (git push --force) to update the remote. This can disrupt teammates. Only use reset for commits that haven't been shared.

Understanding Git Restore

Introduced in Git 2.23, git restore was designed to replace the ambiguous git checkout and git reset commands when dealing with working tree files and the staging area. It focuses solely on restoring file states from different sources.

Why Restore Matters

How to Use Git Restore

Discard local changes in the working directory for a specific file (reverts to the version in the index):

git restore file.txt

Discard all local working directory changes (use with caution):

git restore .

Unstage a file (remove from staging area, keeping the working tree unchanged):

git restore --staged file.txt

Restore a file from a specific commit (without changing branches):

git restore --source abc123 file.txt

This places the version of file.txt as it existed in commit abc123 into your working directory. You can also combine with --staged to update the staging area directly:

git restore --source abc123 --staged file.txt

Restore both working directory and staging area to match a commit:

git restore --source HEAD~1 --staged --worktree file.txt

When you need to undo a bad merge or cherry-pick, restore can also help by reverting the working tree state. For example, to discard all uncommitted changes across the entire project:

git restore --source HEAD --staged --worktree .

Comparing Revert, Reset, and Restore

Although all three commands can "undo" something, they operate at different levels and have distinct consequences:

Here's a quick decision guide:

Best Practices

Conclusion

Git provides multiple ways to undo changes, each tailored to a specific situation. git revert keeps history safe and is your go-to for public commits. git reset rewrites local history with precision and power. git restore handles file-level recovery without touching the branch pointer. Understanding their differences and applying the right command in the right context will keep your repository clean, your team productive, and your stress levels low. Master these three tools, and you'll navigate any Git mishap with confidence.

πŸš€ Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started β€” $23.99/mo
← Back to all articles