Git Reset Explained (Soft vs Mixed vs Hard) with Examples

Git Reset Explained (Soft vs Mixed vs Hard) with Examples

Git reset is a powerful command used to undo commits, unstage changes, or completely discard local modifications. By moving the HEAD pointer, it allows you to control how changes are preserved across the staging area and working directory. Understanding its modes soft, mixed, and hard is essential for safely managing your Git workflow.


Git Reset Cheat Sheet

DescriptionCommand
Undo last commit but keep changes stagedgit reset --soft HEAD~1
Undo last commit and unstage changesgit reset --mixed HEAD~1
Undo last commit and delete all changesgit reset --hard HEAD~1
Unstage a specific filegit reset HEAD file.txt
Unstage all filesgit reset
Reset to a specific commit (keep changes)git reset --soft <commit-hash>
Reset to a specific commit (unstage changes)git reset --mixed <commit-hash>
Reset to a specific commit (delete changes)git reset --hard <commit-hash>
Reset current branch to match remotegit fetch origin && git reset --hard origin/main
Remove all local changes permanentlygit reset --hard
Move HEAD back by 2 commitsgit reset HEAD~2
Reset a file to last commit stategit checkout -- file.txt
Recover from accidental reset (using reflog)git reflog
Reset staged files but keep working changesgit reset --mixed
Reset without specifying mode (default mixed)git reset HEAD~1
Reset only specific file from staginggit reset HEAD file.txt
Reset branch pointer without touching filesgit reset --soft <commit>
Forcefully align branch with remotegit reset --hard origin/<branch>

Git Reset Soft vs Mixed vs Hard

Difference between soft vs mixed vs hard

Git reset provides three modes soft, mixed, and hard each controlling how changes are handled across commit history, staging area, and working directory. The --soft mode only moves the HEAD pointer, --mixed (default) resets the staging area, and --hard removes everything including local changes.

Understanding these differences is critical when undoing commits or fixing mistakes in your Git workflow.

How git reset affects HEAD

The HEAD in Git represents the current commit your branch is pointing to. When you run git reset, Git moves the HEAD to a specified commit (for example, HEAD~1 or a commit hash).

This operation rewrites history locally, which means commits after that point are no longer referenced. You can learn more about HEAD references and how commit navigation works.

How git reset affects staging area

The staging area (index) is where changes are prepared before committing. With git reset --mixed (default), all staged changes are moved back to the working directory and become unstaged.

This is particularly useful when you accidentally staged files and want to undo that action. For similar workflows, check git unstage files and git undo add.

How git reset affects working directory

The working directory contains your actual files. Only git reset --hard modifies the working directory by discarding all local changes and restoring files to the selected commit state.

This is a destructive operation and should be used carefully. If your goal is only to discard changes safely, you can also explore git discard changes or git clean.


Git Reset Commands Explained

git reset --soft

The --soft option moves the HEAD to a previous commit but keeps all changes staged. This is ideal when you want to modify the last commit or combine commits without losing work.

text
git reset --soft HEAD~1

This is commonly used before rewriting commit history using commands like git commit ammend examples or git change commit message.

git reset --mixed

The --mixed option resets the staging area but keeps changes in the working directory. This is the default behavior when no option is specified.

text
git reset HEAD~1

Use this when you want to unstage files but continue working on them.

git reset --hard

The --hard option resets everything—HEAD, staging area, and working directory. All local changes are permanently deleted.

text
git reset --hard HEAD~1

This command is useful when you want to completely discard changes or align your branch with a clean state. In scenarios involving remote sync, it is often combined with git fetch command.

If you accidentally run this command, recovery may still be possible using git reflog.

git reset without options

When no option is provided, Git uses --mixed by default. This means the commit pointer moves back, and all staged changes become unstaged but remain in the working directory.

text
git reset HEAD~1

This behavior makes it safe for everyday use when you want to adjust commits without losing work. You can compare this behavior with safer alternatives like git revert when working in shared environments.


Common Git Reset Use Cases (Real-World)

Undo last commit but keep changes

One of the most common use cases of Git reset is undoing the last commit without losing your work. This is useful when you made a commit too early or want to modify the commit message or contents.

text
git reset --soft HEAD~1

All changes remain staged, allowing you to recommit them easily. You can further refine your commit using git commit ammend or update the message using git change commit message.

Unstage files without losing changes

If you accidentally staged files using git add, you can unstage them without deleting your work using the default mixed reset.

text
git reset HEAD file.txt

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

Discard all local changes permanently

When you want to completely remove all local modifications and revert to the last committed state, use a hard reset.

text
git reset --hard

This command deletes all uncommitted changes permanently. Use it carefully, and consider safer alternatives like git discard changes or git clean when needed.

Reset branch to previous commit

You can move your branch back to a previous state using commit references like HEAD~1 or HEAD~2.

text
git reset --hard HEAD~1

This is useful when you want to remove recent commits entirely. Learn more about commit navigation in git head caret Vs tilde sign.

Reset local branch to match remote

To discard all local changes and align your branch with the remote repository, use:

text
git fetch origin
git reset --hard origin/main

This ensures your branch matches the remote state exactly. You can understand the difference between fetching and pulling.

Fix wrong commit or commit message

If you committed incorrect changes or used a wrong commit message, reset can help you fix it.

text
git reset --soft HEAD~1

Then recommit with corrected details. You can also use git commit ammend or git change commit message for simpler fixes.


Working with HEAD in Git Reset

git reset HEAD

This command resets the staging area by removing all staged files while keeping changes in the working directory.

text
git reset HEAD

It is commonly used after accidentally staging multiple files. For related workflows, refer to git unstage files.

git reset HEAD~1

This moves the HEAD pointer one commit back, effectively undoing the last commit.

text
git reset HEAD~1

By default, this performs a mixed reset, keeping changes but unstaging them.

git reset HEAD~2

This command moves HEAD back by two commits, removing both commits from the current branch history.

text
git reset HEAD~2

It is useful when multiple recent commits need to be undone in one step.

git reset to specific commit

You can reset your branch to any specific commit using its hash.

text
git reset --hard <commit-hash>

This is useful when reverting to a stable state. If needed, you can inspect commits using git show command before resetting.


Git Reset for Files vs Commits

Reset specific file using git reset

Git reset can be used to unstage a specific file without affecting others.

text
git reset HEAD file.txt

This only affects the staging area and does not modify commit history.

Reset all files in staging area

To unstage all files at once, you can run:

text
git reset

This is equivalent to a mixed reset and is commonly used after staging multiple files unintentionally.

Difference between file reset and commit reset

File-level reset only affects the staging area and does not change commit history, while commit-level reset moves the HEAD pointer and can alter history.

Use file reset for minor corrections and commit reset for undoing commits. For safer alternatives that preserve history, consider using git revert command.


Advanced Git Reset Scenarios

Reset after pushing to remote

Resetting commits after pushing to a remote repository can be risky because it rewrites history that others may already be using. If you still need to proceed, you must force push the updated history.

text
git reset --hard HEAD~1
git push --force

This approach should be used cautiously in collaborative environments. A safer alternative is to use git revert command, which creates a new commit instead of rewriting history.

Reset shared branch safely

When working on shared branches, avoid using git reset --hard unless absolutely necessary. Instead, prefer history-preserving commands.

text
git revert <commit-hash>

This ensures that the commit history remains intact while undoing changes. Learn more about safe workflows and git merge vs rebase.

Recover from accidental hard reset

If you accidentally run a hard reset and lose changes, Git still keeps a reference to previous commits using reflog.

text
git reflog
git reset --hard <previous-commit>

This allows you to recover lost commits quickly. For a complete guide, refer to git reflog.

Use git reflog after reset

The git reflog command tracks all HEAD movements, including resets, rebases, and checkouts.

text
git reflog

You can use it to identify previous states and restore them if needed. This is especially useful after destructive operations like git reset --hard.


Common Errors and Fixes

fatal cannot do hard reset with paths

This error occurs when you try to use --hard with a specific file path, which is not supported.

Incorrect usage:

text
git reset --hard file.txt

Fix:

text
git reset --hard

Use file-level operations with mixed reset instead:

text
git reset HEAD file.txt

fatal cannot do soft reset with paths

The --soft option works only at the commit level and does not support file paths.

Incorrect usage:

text
git reset --soft file.txt

Fix:

text
git reset --soft HEAD~1

Use this when you want to undo commits while keeping changes staged.

git reset not working as expected

If git reset does not behave as expected, check:

  • Current branch and HEAD position using git status
  • Commit reference accuracy
  • Whether changes are staged or unstaged

You can inspect differences using git diff command and verify commit history.

changes lost after hard reset

This happens when git reset --hard removes uncommitted changes permanently.

Recovery steps:

text
git reflog
git reset --hard <commit-hash>

If the changes were never committed, recovery may not be possible. To avoid this, consider using git stash command before performing risky operations.


Frequently Asked Questions

1. What is git reset?

Git reset is a command used to undo changes by moving the HEAD pointer to a specific commit. It can modify the staging area and working directory depending on the mode used (soft, mixed, or hard).

2. What is the difference between git reset soft, mixed, and hard?

Soft reset moves the HEAD but keeps changes staged, mixed reset unstages changes but keeps them in the working directory, and hard reset removes all changes from both staging area and working directory.

3. What does git reset --soft do?

Git reset --soft moves the HEAD to a previous commit but keeps all changes staged, allowing you to recommit them easily.

4. What does git reset --hard do?

Git reset --hard resets the HEAD, staging area, and working directory to a specific commit, permanently discarding all local changes.

5. What does git reset --mixed do?

Git reset --mixed resets the staging area while keeping changes in the working directory. It is the default mode of git reset.

6. Is git reset safe to use?

Git reset is safe when used carefully. However, using --hard can permanently delete changes, so it should be used with caution.

Summary

Git reset is a powerful command for undoing commits, unstaging changes, and managing local history. The --soft, --mixed, and --hard modes provide different levels of control over how changes are preserved or removed.

While it is extremely useful for fixing mistakes, it should be used carefully—especially in shared repositories—since it can rewrite commit history and delete changes permanently.


Further Reading

Deepak Prasad

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.