Git

What Does Git Reset Do? Discover Its Use

What Does Git Reset Do? Discover Its Use

Every developer has that moment. You commit something you shouldn’t have, or you stage the wrong files, and you need to undo it. Fast. That’s usually when people ask what does git reset do, and the answers they find are either too vague or way too technical.

Git reset moves your branch’s HEAD pointer to a different commit, with the option to also change your staging area and working directory. Simple concept. But the three modes (--soft, --mixed, --hard) behave very differently, and picking the wrong one can wipe out uncommitted work.

This article covers how each reset mode works, when to use reset vs revert vs checkout, how to recover if things go wrong, and the mistakes that trip up even experienced developers.

What Is Git Reset

maxresdefault What Does Git Reset Do? Discover Its Use

Git reset is a command that moves the current branch’s HEAD pointer back to a specified commit. It changes the state of your git repository by rewriting local commit history, with options to also modify the staging area and working directory.

That description sounds clean. The reality is messier.

Took me a while to actually understand what this command does under the hood. Most people run it to undo a commit or unstage files, and that’s fine. But git reset operates on three internal structures that Git uses to track your work: the HEAD reference, the index (staging area), and the working directory.

HEAD is a pointer to the current branch’s latest commit. The index is your staging area, the snapshot Git will use for your next commit. The working directory is where your actual files live on disk.

Git reset moves HEAD to a different commit, and depending on which flag you pass, it may also reset the index and overwrite your working directory. That’s the core of it.

Hutte research shows 80% of developers use git reset and git revert to undo changes. The two commands get lumped together constantly, but they work very differently. Git reset rewrites history. Git revert creates a new commit that undoes a previous one, leaving the original intact.

If you’re working locally and haven’t pushed anything, git reset is usually the right call. If you’ve already shared commits with a team on a remote repository, revert is safer. Mixing these up is one of the most common mistakes in source control management.

Why is GitHub the heart of open source?

Uncover GitHub statistics: developer community growth, repository trends, collaboration patterns, and the platform that powers modern software development.

Explore GitHub Data →

How the Three Reset Modes Work

maxresdefault What Does Git Reset Do? Discover Its Use

The behavior of git reset changes entirely based on which flag you use. There are three: --soft, --mixed, and --hard. Each one affects a different combination of Git’s three trees.

Here’s the quick breakdown:

FlagMoves HEADResets IndexOverwrites Working Directory
–softYesNoNo
–mixedYesYesNo
–hardYesYesYes

According to Hutte research, 70% of developers have used a Git command without fully understanding what it does. Git reset is probably near the top of that list.

git reset –soft

Soft reset only moves the HEAD pointer. Your staging area stays exactly as it was. Your working directory stays untouched.

Practical example: you just committed something and realized the commit message is wrong, or you want to combine it with another change. Run git reset --soft HEAD~1 and your commit disappears from history, but all the changes sit staged and ready for a new commit.

I use this one a lot for squashing commits before pushing. It’s the least destructive option.

git reset –mixed

This is the default. If you type git reset HEAD~1 without a flag, you get mixed behavior.

It moves HEAD and resets the index. Your files in the working directory stay the same, but they’re no longer staged. You’d need to run git add again to re-stage them.

This is the mode most people actually want when they say “undo my last commit.” Your code changes survive, they’re just unstaged.

git reset –hard

This one is destructive. Period.

It moves HEAD, resets the index, and overwrites every tracked file in your working directory to match the target commit. Any uncommitted changes are gone. No confirmation prompt, no safety net.

Hutte data shows 45% of developers have been negatively affected by a colleague’s force push. A careless --hard reset followed by a force push is usually how that happens. Use this only when you’re absolutely sure you want to throw away everything since a specific commit.

Git Reset vs Git Revert vs Git Checkout

maxresdefault What Does Git Reset Do? Discover Its Use

These three commands confuse everyone. And honestly, the Git documentation doesn’t make it easier. Let me break down what each one actually does, because picking the wrong one can cost you hours.

git reset: Moves the branch pointer backward. Rewrites commit history. Works on the branch level. Best for local, unpushed changes.

git revert: Creates a brand new commit that undoes a previous commit. Doesn’t touch existing history. Safe for shared branches.

git checkout: Switches branches or restores individual files. Doesn’t change branch history at all. Since Git 2.23, git switch and git restore handle these tasks separately.

CommandChanges HistorySafe for Shared BranchesPrimary Use
git resetYesNoUndo local commits, unstage files
git revertNoYesUndo pushed commits safely
git checkoutNoYesSwitch branches, restore files

An ACM study analyzing 80,370 Git-related questions on Stack Overflow found that developers frequently struggle to distinguish between these commands. And it makes sense. The naming is confusing.

The rule I follow: if the commits are only on your machine, use reset. If anyone else has pulled those commits, use revert. If you just want to look at an older version or switch branches, use checkout (or switch/restore in newer Git versions).

How to Undo a Commit with Git Reset

maxresdefault What Does Git Reset Do? Discover Its Use

This is the main reason people search for this command. Something went wrong, and you want to take it back.

The most common scenario: you just made a commit and immediately regret it. Maybe you committed the wrong files, or the code has a bug, or the message is garbage.

Undo last commit, keep changes staged:

git reset --soft HEAD~1

Your commit hash disappears from the log, but everything stays staged. Ready for a fresh commit whenever you want.

Undo last commit, unstage the changes:

git reset HEAD~1

Same thing, but your files drop out of the staging area. You’ll need to git add them again. This is the default mixed mode.

Undo last commit and delete all changes:

git reset --hard HEAD~1

Gone. Your code goes back to exactly how it looked before that commit. Nothing recoverable in the working directory (though the reflog still has your back, which I’ll cover later).

What about undoing multiple commits? Just change the number. HEAD~3 goes back three commits. Or you can target a specific commit hash directly:

git reset --soft abc1234

That resets to whatever commit abc1234 points to. Check git log first to find the right hash. Your mileage may vary here, especially if the commits touched the same files across multiple changes.

GitHub’s Octoverse 2025 report shows developers pushed nearly 1 billion commits across the platform that year, a 25% increase over the prior year. With that volume, undoing commits is not an edge case. It’s a daily occurrence for a lot of teams.

How to Unstage Files with Git Reset

maxresdefault What Does Git Reset Do? Discover Its Use

Second most common use. You ran git add on something you didn’t mean to stage, and now you want to pull it back out before committing.

Unstage a specific file:

git reset HEAD myfile.js

The file stays in your working directory with all changes intact. It’s just no longer part of the next commit.

Unstage everything:

git reset

No arguments needed. This clears the entire staging area without touching your actual files.

If you’ve used Git for a while, you might remember that git status used to suggest git reset HEAD <file> as the way to unstage a file. Since Git 2.23, the recommended command is git restore --staged <file>, which does the same thing with clearer naming.

Both work fine. But git restore --staged is less confusing for people who are still learning the difference between reset modes. The old way isn’t deprecated or anything, it just carries more cognitive load when you’re also thinking about --soft and --hard flags in other contexts.

Stack Overflow’s 2022 survey noted that 65% of developers still prefer using Git through the command line over graphical tools, according to Hutte research. So knowing these commands by heart actually matters more than you’d think in a world full of GUI options.

Git Reset with Remote Branches

maxresdefault What Does Git Reset Do? Discover Its Use

Here’s where things get tricky. And dangerous.

Git reset rewrites history. That’s fine on your local machine. But the moment you’ve pushed commits to a shared branch, resetting creates a mess for everyone who’s already pulled those commits.

Think about it this way: your teammates based their work on commit A, B, and C. You reset back to A and force push. Now their local branches reference commits that no longer exist on the remote. Their next pull or push throws errors, and they have to manually reconcile the divergence.

Hutte data shows 45% of developers have been negatively impacted by a colleague’s force push. That stat alone should make you pause before running git push --force after a reset.

When force pushing is acceptable:

  • Personal feature branches that nobody else has checked out
  • Pre-review work you’re cleaning up before a pull request
  • Branches explicitly marked as “rebase-friendly” in your team’s git workflow

The safer option: git push --force-with-lease

This flag checks whether the remote branch has been updated since your last fetch. If someone else pushed in the meantime, Git rejects the force push instead of blindly overwriting their work. It’s not bulletproof, but it catches the most common failure mode.

For already-pushed commits on shared branches, reverting a commit is almost always the better choice. It creates a new commit that undoes the change without rewriting any history. Everyone stays in sync.

Atlassian’s Git documentation puts it bluntly: you should never use git reset on commits that have been pushed to a public repository. After publishing a commit, assume other developers depend on it. That’s solid advice, and it applies whether you’re working in a small startup or a team of hundreds using GitHub or GitLab.

Git adoption overall has climbed from 87.1% in 2016 to 93.87% in 2025, according to Stack Overflow survey data compiled by Command Linux. More developers using Git means more shared branches and more situations where a careless reset on already-pushed code creates real problems for your team’s software development process.

How to Recover After a Git Reset

maxresdefault What Does Git Reset Do? Discover Its Use

You ran git reset --hard and immediately felt that sinking feeling. The commits are gone from git log. Your working directory just snapped back to some earlier state.

Deep breath. The work is probably still there.

Git keeps a hidden diary called the reflog (reference log). Every time HEAD moves, whether from a commit, reset, rebase, or branch switch, Git records the change. Even after a hard reset wipes commits from your visible history, reflog still remembers where HEAD pointed before you ran the command.

Step-by-step recovery:

  1. Run git reflog to see the full list of HEAD movements
  2. Find the commit hash from just before your reset
  3. Run git reset --hard <that-hash> to jump back to it

That’s it. Three steps. The commit you thought was gone is now the tip of your branch again.

If you’d rather not move your current branch, you can create a new branch from the lost commit instead: git branch recovery-branch <hash>. This lets you inspect the recovered work without touching anything else.

Reflog retention period: By default, Git keeps reflog entries for 90 days on reachable commits and 30 days on unreachable ones. After that, git gc (garbage collection) can permanently remove them. So don’t wait months to recover something.

When recovery is NOT possible:

  • Uncommitted changes wiped by --hard (never staged or committed, truly gone)
  • Reflog entries expired and garbage collection already ran
  • Working on a bare repository with no reflog enabled

The Atlassian Git documentation notes that reflog is strictly local. It doesn’t get pushed to remotes, and you can’t use it to recover another developer’s unpushed commits. Each developer’s reflog tracks only their own actions.

Hutte research shows 28% of developers have been confused or lost work when using git stash. The same pattern applies to reset. Most developers learn about reflog recovery only after they’ve already lost something. Building a habit of checking git reflog before any destructive operation saves real headaches, especially during a complex rebase or history cleanup.

Common Git Reset Mistakes

maxresdefault What Does Git Reset Do? Discover Its Use

Knowing the command is half the battle. Knowing what goes wrong is the other half.

Hutte data shows 70% of developers have used a Git command without fully understanding its implications. With git reset, the consequences range from mildly annoying to genuinely destructive.

Running –hard when you meant –mixed

This is the big one. You wanted to undo a commit but keep your code changes. You typed --hard instead of leaving the flag off (which defaults to --mixed).

Result: all uncommitted work in tracked files gets overwritten instantly. No warning, no prompt.

If you caught it immediately, git reflog can bring committed changes back. But anything you hadn’t committed yet is gone for good.

Resetting commits that were already pushed

According to Hutte research, 45% of developers have been negatively impacted by a colleague’s force push. That chain usually starts with someone running git reset on already-pushed commits and then force pushing to “fix” things.

The remote branch now has different history than what everyone else pulled. Merge conflicts, detached HEAD states, and confused teammates follow.

Use git revert for pushed commits. Always.

Confusing HEAD~1 with HEAD@{1}

These look similar but point to completely different things.

NotationMeaningWhere It Looks
HEAD~1One commit before current in ancestryCommit history
HEAD@{1}Previous HEAD position (before last move)Reflog

After a reset, HEAD~1 refers to one commit before the new position. HEAD@{1} refers to where HEAD was before the reset happened. These are not the same commit.

Forgetting that untracked files are safe

Quick reassurance: git reset --hard does not touch untracked files. New files that were never staged or committed stay in your working directory.

If you need to remove those too, that’s what git clean is for. A separate command with its own set of flags.

Skipping git status before reset

Running git status before a reset takes two seconds. It shows you exactly what’s staged, what’s modified, and what’s untracked. Skipping it means you’re gambling on memory.

Developers who consistently run git status and check git diff before destructive commands rarely lose work. It’s the simplest safety habit in version control.

Git Reset in GUI Clients and IDEs

maxresdefault What Does Git Reset Do? Discover Its Use

Not everyone lives in the terminal. According to the Stack Overflow 2025 Developer Survey, VS Code holds 75.9% developer market share, and its built-in Git integration means a lot of reset operations happen through a graphical interface.

The problem is that most GUI tools abstract away the reset modes. You click “undo commit” and don’t always know if you’re getting soft, mixed, or hard behavior.

VS Code Source Control

VS Code’s Source Control panel shows staged changes, modified files, and the commit timeline. You can right-click a commit in the Git Graph extension to reset.

What’s available: soft reset, mixed reset, and hard reset options are all accessible through the extension’s context menu. The inline integrated terminal also gives you direct command-line access without switching windows.

GitKraken and Sourcetree

GitKraken offers a visual commit graph where you can right-click any commit and choose “Reset to this commit” with soft, mixed, or hard options. It also shows a warning banner when you attempt a force push after a reset, giving you a chance to cancel.

Sourcetree (by Atlassian) has similar reset functionality through its Log/History view. Both tools also surface reflog data, which is useful for recovery.

JetBrains IDEs

IntelliJ, WebStorm, and other JetBrains tools have a built-in “Undo Commit” feature under the Git menu. This maps to a --mixed reset by default.

JetBrains IDEs also maintain their own local history system separate from Git. Even if a hard reset wipes your Git history, the IDE’s local history may still hold the file contents, which has saved me more than once.

GitHub Desktop

GitHub Desktop keeps things simple. It offers a single “Undo” button for the most recent commit, equivalent to git reset --mixed HEAD~1.

No --soft or --hard option in the UI. If you need those, open the integrated terminal or switch to another tool. Useful for beginners who want fewer ways to break things.

Why command-line knowledge still matters

Every GUI client eventually hits a wall. Complex resets, interactive rebases, selective reflog recovery, these all push you back to Git commands in the terminal.

The Hutte research stat holds up here: 65% of developers still prefer the command line for Git. GUI tools are fine for everyday staging and commits, but when you need precision (and when things go sideways), the terminal is where the real control lives.

Understanding how git reset works at the command level also means you can follow documentation, Stack Overflow answers, and technical documentation without guessing which GUI button maps to which flag.

FAQ on What Does Git Reset Do

Does git reset delete my files?

Only with --hard. A hard reset overwrites tracked files in your working directory to match the target commit. The –mixed and –soft flags leave your actual files untouched. Untracked files are never affected by any reset mode.

What is the difference between git reset and git revert?

Git reset rewrites commit history by moving the HEAD pointer backward. Git revert creates a new commit that undoes a previous one without changing existing history. Use revert for already-pushed commits on shared branches.

What does git reset HEAD do?

It unstages all files from the staging area without changing your working directory. Your code stays the same, but nothing is queued for the next commit. Since Git 2.23, git restore --staged does the same thing.

Can I undo a git reset?

Yes, in most cases. Run git reflog to find the commit hash from before your reset, then use git reset --hard <hash> to jump back. Reflog entries last 90 days by default before garbage collection removes them.

What is the default mode of git reset?

The default is --mixed. It moves HEAD and resets the index (staging area) but keeps your working directory files unchanged. Running git reset HEAD~1 without a flag uses this mode automatically.

Is git reset dangerous?

It depends on the flag. The --soft and --mixed modes are safe for local work. The –hard flag is destructive because it overwrites uncommitted changes permanently. Always check git status before running a hard reset.

Can I git reset a single file?

Yes. Running git reset HEAD myfile.js removes that specific file from the staging area without affecting other staged files or your working directory. It’s the opposite of git add for that file.

What happens to commits after git reset?

They become unreachable from any branch but still exist in the repository temporarily. Git’s reflog tracks them, and they stay recoverable until garbage collection runs. That’s usually 30 to 90 days depending on your config.

Should I use git reset on shared branches?

No. Resetting rewrites history, which causes problems for anyone who already pulled those commits. Use git revert instead for shared branches. If you must reset, communicate with your team and use --force-with-lease when pushing.

What is the difference between git reset –soft and –hard?

Soft reset only moves HEAD. Your staged changes and working directory stay intact. Hard reset moves HEAD, clears the staging area, and overwrites your working directory. Everything uncommitted gets wiped with –hard.

Conclusion

Understanding what does git reset do comes down to knowing which of the three modes fits your situation. Soft keeps everything staged. Mixed unstages but preserves your files. Hard wipes it all.

The distinction between reset and git revert matters most when commits have already been pushed. Reset rewrites history locally. Revert keeps the commit log intact for everyone on the team.

If something goes wrong, git reflog is your recovery tool. It tracks every HEAD movement for up to 90 days, giving you a way back from most mistakes.

Check git status before running destructive commands. Use –force-with-lease instead of –force when pushing after a reset. And keep your local branch clean before sharing work with a remote repository.

These habits turn git reset from a risky command into a precise one. Learn the flags, respect shared branches, and you’ll rarely run into trouble.

50218a090dd169a5399b03ee399b27df17d94bb940d98ae3f8daff6c978743c5?s=250&d=mm&r=g What Does Git Reset Do? Discover Its Use

Stay sharp. Ship better code.

Every week: one curated article, one tool worth knowing, one tip you can use tomorrow. No noise, no padding.