What Does Git Reset Do? Discover Its Use

Ever accidentally committed the wrong files or needed to undo changes in your Git repository? The git reset command is your time machine for version control. Unlike other Git operations, reset gives you precise control over three critical areas: the commit history, staging area, and working directory.
Git reset directly manipulates the HEAD pointer and can modify your project’s state in seconds. Whether you’re trying to undo a git commit, clean up your branch history, or unstage changes you’ve made by mistake, understanding reset is essential for any developer working with Git.
This guide explains exactly what git reset does in different scenarios. You’ll learn:
- The three reset modes (soft, mixed, and hard) and when to use each
- How reset compares to other commands like revert and checkout
- Advanced techniques for safely manipulating your git history
- Recovery options when things go wrong
Master this powerful command to gain complete control over your Git workflow.
What Does Git Reset Do?
Git reset is a command that undoes changes in a Git repository by moving the current branch to a different commit. It can modify the staging area, working directory, or both, depending on options used. Git reset is often used to unstage files, discard commits, or redo changes carefully.
Git Reset Modes Explained

Git reset is a powerful command line interface tool that manipulates the Git HEAD reference and modifies your Git repository state. Unlike other version control system commands, reset gives you precise control over three key areas: the commit history, staging area, and working directory.
Soft Reset (–soft)
The soft reset option moves your HEAD pointer without touching your working files or staging area. It’s the gentlest form of git reset.
What Changes With Soft Reset
When you run git reset --soft <commit>
, only the HEAD reference changes. Your git index changes remain staged, and working directory files stay untouched. This creates a perfect scenario for git commit manipulation.
git reset --soft HEAD~1
This command moves HEAD back one commit while keeping all changes staged. Your work remains intact—only the commit pointer moves.
When To Use Soft Reset
Soft reset shines when you need to:
- Undo git commit without losing work
- Combine multiple small commits into one larger commit
- Fix a commit message without changing the actual work
- Perform a rewrite git history operation safely
Practical Examples
Forgot to add a file to your last commit? Soft reset lets you fix it:
git reset --soft HEAD~1
to move back one commit- Add the missing file:
git add forgotten-file.txt
- Recommit with a better message:
git commit -m "Complete feature with all files"
This workflow is much cleaner than creating a new “oops” commit.
Mixed Reset (–mixed)
Mixed reset is the default reset behavior when no flag is specified. It affects both the HEAD reference and the staging area.
Effects on Staging Area and Working Directory
When performing a mixed reset:
- The commit tree moves to the specified commit
- All changes from undone commits move to the working directory
- The staging area is reset to match the target commit
- Working directory files remain untouched
This effectively “unstages” any changes that were part of the removed commits.
git reset HEAD~2 # Same as git reset --mixed HEAD~2
This command reference example moves your HEAD back two commits and unstages all changes.
Common Use Cases
Mixed reset works best for:
- Unstage changes you’ve added by mistake
- Reorganizing changes into different commits
- Starting over with your staging after a messy series of adds
- Git reset staged files when you need to rethink your commit structure
Mixed reset is the perfect middle ground—it preserves your work while giving you a clean staging area.
Hard Reset (–hard)
Hard reset is the most drastic git reset option. It completely synchronizes all three areas: HEAD, index, and working directory.
Complete Reset to Specified Commit
When you execute git reset --hard <commit>
, Git:
- Moves the HEAD pointer to the target commit
- Overwrites the staging area to match that commit
- Discard uncommitted changes in your working directory
This creates a clean slate, as if you’d just checked out that commit fresh.
git reset --hard a1b2c3d
This command will reset everything to the state at commit a1b2c3d
, discarding all newer changes.
Data Loss Warnings
⚠️ Git reset hard is dangerous! Any uncommitted work or commits after your target point will be lost. This can erase hours of work in a second.
Always consider these git reset dangers before using --hard
:
- Unsaved work will vanish
- Commits not referenced by other branches may become unreachable
- You could lose significant progress with no simple undo
When working in a team environment, hard reset can disrupt other developers if used on shared branches.
Recovery Options After Hard Reset
If you experience git reset recover panic, don’t worry immediately. Git keeps a record of all reference changes in the git reflog:
git reflog
This shows a history of where your HEAD has been. You can often recover lost commits with:
git reset --hard HEAD@{1} # Goes back to where HEAD was before the last command
The reflog is your safety net, but it’s temporary (usually 30-90 days). Don’t rely on it for long-term recovery.
Common Use Cases for Git Reset
Undoing Commits
One of the most frequent uses of reset is to undo recent commits in your local Git repository.
Removing the Last Commit
To undo your most recent commit while keeping the changes:
git reset --soft HEAD~1
This keeps all your work staged and ready for a new commit. Perfect for when you need to fix git mistakes in a commit message or add forgotten files.
For complete removal of the last commit and its changes:
git reset --hard HEAD~1
This is the nuclear option that completely removes staged changes along with the commit.
Rewriting Multiple Commits
When your source code management needs include cleaning up a series of messy commits:
git reset --soft HEAD~3
git commit -m "One clean, comprehensive commit"
This technique is useful before submitting pull requests to GitHub or GitLab, consolidating experimental commits into one polished change.
Keeping vs. Discarding Changes
The key decision with any reset is what to keep:
- –soft: Keep all changes staged
- –mixed: Keep all changes but unstaged
- –hard: Discard all changes
Your choice depends on your immediate goals:
- Need to reorganize changes? Use
--mixed
- Want to combine commits? Use
--soft
- Need to abandon everything? Use
--hard
Cleaning Up Branches
Git reset excels at managing your git branch structure and history.
Reset vs. Rebase for Branch Cleanup
Both reset and git rebase can clean history, but they work differently:
- Reset: Changes where your branch points, potentially discarding commits
- Rebase: Replays commits on a new base, preserving each change
Reset is simpler but more destructive. Rebase preserves history but can be complex to resolve if conflicts arise.
# Reset approach - clean but destroys history
git reset --hard origin/main
# Rebase approach - preserves your work as new commits
git rebase origin/main
For personal feature branches, reset is often faster. For shared work, rebase is safer.
Managing Feature Branches
When working with feature branches in a distributed version control workflow:
- Create a checkpoint branch before reset:
git branch backup-feature
- Then safely reset your main feature branch:
git reset --mixed main
This technique gives you freedom to experiment with git reset branch operations while keeping a safety net.
Preparing for Merges
Before merging into important branches like main:
git fetch origin
git reset --hard origin/main
git merge feature-branch
This ensures you’re working with the latest code. It helps avoid incorrect merges and unnecessary merge commits.
Fixing Mistakes
Git reset is the go-to tool for fixing various common mistakes.
Removing Accidentally Committed Files
Did you commit a huge file, passwords, or other unwanted content? Fix it with reset:
git reset --mixed HEAD~1
git add -A # Add everything back except the problematic file
git commit -m "Same changes without the unwanted file"
This technique is invaluable when you need to remove sensitive information or binary files from your commit history.
Unstaging Files Without Losing Changes
To unstage a specific file without affecting others:
git reset HEAD path/to/file.txt
This git reset specific file command lets you selectively unstage changes while keeping your work intact.
Recovering from Incorrect Merges
If you merge the wrong branch or encounter severe conflicts:
git reset --hard HEAD@{1} # Return to pre-merge state
This git reset recover technique uses the reflog to back out of problematic merges completely.
When working within a git workflow, always consider whether others have seen your commits before resetting. For public branches, git revert might be a better, safer option than reset.
Remember that git reset is primarily for local history rewrites. For collaborative work on GitHub or BitBucket, communicate with your team before using reset operations that affect shared branches.
Git Reset vs. Other Git Commands
Working with Git involves understanding when to use specific tools for particular situations. Git reset is powerful but not always the right choice compared to other version control system commands.
Reset vs. Revert

Git reset and git revert both undo changes, but they work fundamentally differently.
Public vs. Private Branch Considerations
The key difference lies in how they handle history:
- Git reset rewrites history by removing commits completely
- Git revert creates a new commit that undoes previous changes
This distinction matters tremendously when working with others. On a private branch, reset works fine. For shared branches on GitHub or GitLab, revert is safer since it doesn’t disrupt the history others have already pulled.
# Dangerous for shared branches
git reset --hard HEAD~3
# Safe for any branch
git revert HEAD~3..HEAD
When collaborating in a team environment, always consider the impact of your git history modifications.
History Preservation Differences
Reset erases history. Revert preserves it. This simple contrast has significant implications:
- Reset: No record remains of the undone commits in normal history view
- Revert: Full transparency of both the original work and its reversal
Your commit tree stays intact with revert, which provides a complete audit trail. This can be crucial for project governance and understanding why changes were made.
When to Choose Each Option
Use reset when:
- Working locally on feature branches nobody else has seen
- Cleaning up before pushing to remote repositories
- Fixing mistakes in recent private commits
- You want to simplify history by removing experimental commits
Use revert when:
- Working on branches others have pulled
- You need to preserve a record of the mistake and its fix
- Undoing a change that’s several commits in the past
- Performing a git rollback command in production environments
Reset vs. Checkout
These commands can seem similar but serve different purposes in your git workflow commands arsenal.
File-Level Differences
At the file level:
git reset <file>
unstages a file without changing its contentsgit checkout <file>
replaces the file with the version from HEAD, discarding local changes
Checkout is more destructive to your working directory changes.
# Unstage a file (keeps modifications)
git reset HEAD file.txt
# Discard local changes to a file
git checkout -- file.txt
Understanding this distinction helps prevent accidental git workflow mistakes.
Branch-Level Differences
When working with branches:
git reset --hard <branch>
moves your current branch to point at another commitgit checkout <branch>
switches between branches without changing their states
Reset actually moves the branch pointer. Checkout just changes which branch you’re viewing.
HEAD Pointer Behavior
The HEAD pointer behaves differently with each command:
- Reset: Moves the branch that HEAD points to
- Checkout: Moves HEAD itself to point to a different branch
This fundamental difference explains why reset can seem more “destructive” – it literally changes what your branch represents in the git object model.
Reset vs. Restore
Modern Git versions introduced git restore
as a clearer alternative to some reset
functions.
Modern Git Alternatives
In recent Git updates, the command set has evolved:
git restore --staged <file>
replacesgit reset HEAD <file>
git restore <file>
replacesgit checkout -- <file>
These new commands more clearly express intent than the overloaded reset and checkout commands.
# Old way (still works)
git reset HEAD file.txt
# New way (clearer intent)
git restore --staged file.txt
This evolution in the command reference makes Git more intuitive for newcomers.
Simplicity vs. Flexibility
Reset remains more powerful but more complex:
- Restore: Focused only on file content restoration
- Reset: Can manipulate commits, references, and file states
For simple unstaging changes or discard uncommitted changes operations, restore provides clearer syntax. For complex git commit manipulation, reset still offers more options.
Migration Path from Reset to Restore
If you’re used to reset, transitioning to restore is straightforward:
Reset Command | Restore Equivalent |
---|---|
git reset HEAD <file> | git restore --staged <file> |
git reset --hard <file> | git restore --source=HEAD --staged --worktree <file> |
These new commands represent a more task-focused approach to git command line tools, making intentions clearer.
Advanced Git Reset Techniques
Beyond basics, reset enables sophisticated git history cleanup techniques.
Partial Resets
You don’t always need to reset entire commits. Git reset supports more surgical operations.
Resetting Specific Files
To reset only certain files to a previous state:
git reset commit_hash -- path/to/file
This command maintains all other changes while reverting only specified files. It’s perfect for situations where a single file was corrupted or when you need to restore just a portion of a previous git repository state.
Combining with git add -p
For even more granular control, combine reset with patch mode:
- Reset files:
git reset HEAD -- file.txt
- Selectively re-add parts:
git add -p file.txt
This flow gives you line-by-line control over what changes remain staged. It’s essential for creating clean, logical commits that represent distinct units of work.
Path-Specific Reset Options
Reset supports path specifications with different modes:
# Unstage specific file (mixed mode is implied for paths)
git reset -- file.txt
# Reset file in index to specific commit
git reset commit_hash -- file.txt
These path-specific reset options help maintain a clean git index without disrupting your entire workspace.
Reset with Merge Conflicts
Merge conflicts represent a special challenge that reset can help solve.
Resolving Conflicts After Reset
When a merge goes wrong, you can reset and try a different approach:
# Abort current merge
git reset --hard HEAD
# Try a different strategy
git pull --rebase
Sometimes a clean slate is better than struggling with complex conflicts.
Abort Options for Complex Situations
For particularly messy situations, you have several reset-based options:
- Soft reset:
git reset --soft HEAD~1
to undo the merge commit but keep all changes - Mixed reset:
git reset HEAD~1
to undo and unstage everything - Hard reset:
git reset --hard HEAD~1
to completely abandon the merge
Your choice depends on whether you want to preserve the work done during conflict resolution.
Reset During Rebase Operations
During a git rebase operation, reset can help manage difficult steps:
# During a troubled rebase
git reset --hard HEAD # Reset the current troubled commit
git rebase --skip # Skip this commit and continue
This technique helps when individual commits in a rebase sequence cause problems.
Git Reset in Team Environments
Using reset in a team environment requires extra caution and communication.
Reset Etiquette for Shared Branches
Follow these guidelines when working with shared code:
- Never reset branches others are working on
- Communicate before force-pushing after a reset
- Consider using revert instead for public history
- Document why the reset was necessary
Respecting these principles helps maintain a healthy distributed version control workflow.
Communication Best Practices
When you must reset shared history:
- Alert team members before resetting
- Explain what commits will be affected
- Give clear instructions for team members to sync
- Provide a recovery path if things go wrong
Good communication transforms a potentially disruptive reset into a coordinated team activity.
Alternatives for Collaborative Work
Instead of resetting shared history, consider:
- Using feature branches for experimental work
- Creating a new clean branch from main and cherry-picking good commits
- Using revert for public-facing fixes
- Employing git branch pointer manipulation through more sophisticated merging strategies
These approaches help preserve stable history in shared repositories like those on GitHub or BitBucket.
The power of git reset comes with responsibility. Used wisely, it keeps your source code management clean and efficient. Used carelessly, it can cause work loss and team friction. Master these advanced techniques, and you’ll wield reset as the precision tool it was designed to be.
Git Reset Safety Measures
Working with git reset can be risky. One wrong command might erase hours of work. Smart developers always use safety nets before attempting any major git history modification.
Creating Backups Before Reset
Before you experiment with git reset hard or other destructive operations, implement these safeguards.
Using Branches as Safety Nets
Branches are your first line of defense against git reset dangers. Create a backup branch before any risky operation:
# Create safety branch pointing at current HEAD
git branch backup-april19
This simple step creates a complete reference to your current state. If anything goes wrong during reset operations, you can always return:
# Recover completely from a bad reset
git checkout backup-april19
git branch -D main
git branch main
git checkout main
This sequence restores your main branch to its pre-reset state. The branch acts as a bookmark in your commit tree.
Stashing Changes
For uncommitted work, git stash provides protection:
# Save working directory and index state
git stash save "Pre-reset backup"
This command safely stores your uncommitted changes. After your reset, you can either apply the stash or simply drop it if no longer needed:
git stash apply # Bring back changes
# or
git stash drop # Discard the backup when confident
Stashing is particularly valuable before a git reset hard that would otherwise destroy your work in progress.
Reflog as a Safety Feature
Git silently records every HEAD reference update in the reflog. This system keeps track of your previous states even after destructive commands.
# View recent activity
git reflog
The output shows entries like:
1a2b3c4 HEAD@{0}: reset: moving to HEAD~3
4d5e6f7 HEAD@{1}: commit: Add feature X
8h9i0j1 HEAD@{2}: commit: Fix bug in module Y
Each entry represents a previous state of your git repository. This log creates a time machine for your repo.
Understanding the Reflog
The reflog is your emergency rescue system when git reset operations go wrong.
How Git Tracks Reset Operations
Every time you run commands that move references (commit, reset, checkout, etc.), Git adds entries to the reflog. These entries persist for about 30 days by default in a standard git configuration.
# See all reference logs
git reflog show --all
This output provides complete visibility into all reference movements, including those caused by destructive reset operations.
Finding Lost Commits
If you’ve lost commits after a git reset hard, find them in the reflog:
- Run
git reflog
to see your history - Identify the commit hash you need to recover
- Use that hash to restore your work
# First, find the lost commit
git reflog
# Then recover it
git checkout -b recovered-work a1b2c3d
This creates a new branch pointing at your rescued commit. From here, you can merge it back into your main branch or continue working directly on the recovery branch.
Recovering from Dangerous Resets
For more complex recovery scenarios:
# Return to state before the last command
git reset --hard HEAD@{1}
# Go back to where you were 2 hours ago
git checkout HEAD@{2.hours.ago}
This technique works for recovering from nearly any reset mistake. The syntax is flexible, supporting time-based references like @{yesterday}
or position-based like @{5}
.
Testing Reset Operations
Safe git workflow includes testing reset operations before finalizing them.
Dry Run Options
When working with unfamiliar git reset commands, preview their effects:
# See what files would be modified but don't actually reset
git checkout --dry-run other-branch
While reset itself doesn’t offer a built-in dry-run option, you can simulate it:
- Create a temporary branch at your current position
- Perform the reset on that branch
- Examine the results
- Switch back to your original branch if you’re not satisfied
Verifying Results Before Pushing
After any reset operation, verify your repository state before sharing:
# See current status
git status
# Review the log
git log --oneline
# Check specific files
git diff HEAD~3 -- important-file.js
These checks confirm that your git reset achieved the desired outcome. Never git push –force without verification, as this can disrupt team members using GitHub, BitBucket, or other shared source code management systems.
Using Git GUIs for Visual Confirmation
Visual tools provide clearer confirmation of reset operations. Popular options include:
- GitKraken
- Sourcetree
- GitHub Desktop
- VS Code’s Git integration
These tools show your commit tree graphically, making it easier to understand the impacts of git reset branch operations before and after execution.
Practical Safety Workflow
Here’s a complete safety workflow for risky git reset operations:
- Backup your current state
git branch backup-before-reset
- Stash any uncommitted changes
git stash save "Pre-reset changes"
- Perform the reset operation
git reset --hard target-commit
- Verify the results
git log --oneline -n 5 git status
- Push with care (if needed)
# Only if working on a personal branch git push --force-with-lease origin branch-name
- Recover if necessary
git checkout backup-before-reset
Remember that git reset is a powerful tool for git repository management. With these safety measures, you can use it confidently while avoiding its pitfalls. The reflog is always watching, ready to save you from even the most catastrophic mistakes when modifying git repository history.
FAQ on What Does Git Reset Do
What’s the difference between git reset –soft, –mixed, and –hard?
Git reset offers three modes that affect different areas. –soft only moves the HEAD reference while keeping staged changes. –mixed (default) moves HEAD and unstages changes. –hard is most destructive, moving HEAD, unstaging changes, and wiping the working directory. Choose based on whether you want to keep or discard changes.
Can I recover commits after a hard reset?
Yes! After a git reset hard, you can recover “lost” commits using the git reflog. This command shows a history of where your HEAD has been. Find the commit hash you need and use git checkout [hash]
to recover it. The reflog keeps entries for about 30 days in your local git repository.
How do I undo my last commit without losing changes?
Use git reset --soft HEAD~1
to undo git commit without losing work. This moves your HEAD pointer back one commit while keeping all changes staged. Your files remain unchanged in the working directory. You can then fix your code, add more files, or create a new commit.
What’s the difference between git reset and git revert?
Git reset rewrites history by removing commits, while git revert creates a new commit that undoes previous changes. Reset is better for private branches, while revert is safer for public branches since it preserves history. Reset changes the past; revert acknowledges mistakes and corrects them.
How do I unstage a file without losing changes?
Use git reset HEAD filename
or the newer git restore --staged filename
to unstage changes without affecting your working directory. This command removes the file from the git index but keeps your modifications intact. It’s perfect for when you accidentally stage files you didn’t intend to commit.
Can git reset be used on specific files?
Yes! The git reset pathspec syntax allows file-specific resets: git reset [commit] -- path/to/file
. This resets only that file to the specified commit state without affecting others. It’s useful for selectively undoing changes to specific files while keeping others intact.
Is it safe to use git reset on shared branches?
No. Using git reset on shared branches like main can disrupt your team environment. It rewrites history, forcing others to deal with conflicts when they pull. For collaborative work, use git revert instead, which preserves history. If reset is necessary, communicate with your team first.
How can I clean up my branch before merging?
Use git reset --mixed origin/main
to align your feature branch with main while keeping your changes. Then recommit them logically. This git reset branch technique helps create a clean history before merging. For public branches, consider interactive rebase instead of reset.
What happens to my work when I use git reset?
It depends on the mode. With –soft, commits are undone but changes remain staged. With –mixed, commits are undone and changes are unstaged but present in your working directory. With –hard, both commits and working changes are discarded. The reset affects your commit tree and potentially your files.
How do I fix a bad merge with git reset?
To fix a problematic merge, use git reset --hard HEAD~1
to completely undo the merge commit. Alternatively, use git reset --merge ORIG_HEAD
to keep your work but undo the merge. Then try different approaches like git rebase or resolving conflicts manually before attempting to merge again.
Conclusion
Understanding what does git reset do transforms your ability to maintain a clean and efficient git repository state. This powerful command gives you precise control over your project’s history, letting you fix mistakes and organize your work with confidence. Its flexibility across different modes makes it invaluable for both beginners and experienced developers using version control systems.
The benefits of mastering git reset include:
- Removing staged changes without losing work
- Cleaning up repository history before sharing code
- Providing recovery options through reflog when mistakes happen
- Creating more logical commit manipulation patterns
- Enabling advanced branch pointer manipulation techniques
While powerful, remember that git reset should be used cautiously on shared work. Always consider using git revert for public branches. The combination of git reflog and temporary branches creates a safety net that makes even the most drastic reset operations reversible.
As you grow more comfortable with git reset options, you’ll find your entire git workflow becoming more efficient. This command isn’t just a tool for fixing mistakes—it’s a key part of maintaining a professional and organized source code management approach.
- What Is MVVM? A Modern Approach to App Architecture - May 22, 2025
- What Is Gitignore? Understand It in 5 Minutes - May 22, 2025
- Why Embedded Systems Are Crucial for Modern Product Success - May 22, 2025