What's the difference between git reset and git checkout?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
git reset and git checkout can both make your repository look like an earlier state, which is why they are often confused. The real difference is that reset mainly moves references and changes the index, while checkout mainly changes what is currently checked out in your working tree.
The Three Git Areas
To understand both commands, keep these three areas in mind:
- '
HEAD: the current commit your branch points to' - index: the staging area
- working tree: the files on disk
The safest mental model is to ask which of those areas a command modifies.
What git reset Does
git reset moves the current branch reference and may also update the index and working tree depending on the mode.
A soft reset moves HEAD only:
Result:
- the last commit is undone
- the changes remain staged
- the working tree still contains those changes
A mixed reset, which is the default, moves HEAD and resets the index:
Result:
- the last commit is undone
- the changes become unstaged
- the working tree still keeps the file modifications
A hard reset changes all three areas:
Result:
- the branch moves back
- staged changes are discarded
- working tree changes are overwritten
That is why --hard is dangerous.
What git checkout Does
Historically, git checkout had two major jobs:
- switch to another branch or commit
- restore file contents from a commit into the working tree
Switching branches:
This updates HEAD to point at a different branch and rewrites the working tree to match that branch.
Checking out a single file from a commit:
This restores that file in the working tree, and often the index as well, to the chosen revision.
Unlike reset, checkout usually does not rewrite branch history. It changes what you have checked out, not what commits exist on the current branch.
A Simple Comparison
If you accidentally made a bad commit and want to keep the code changes but uncommit them, use reset:
If you want to leave history alone and just move to another branch, use checkout:
If you want one file to match the last commit again, checkout can restore it:
These commands may both "undo" something, but they work at different levels.
Modern Git Commands
Newer Git versions split the old checkout behavior into clearer commands:
- '
git switchfor branch changes' - '
git restorefor file restoration'
Examples:
These are often easier to reason about than the older multi-purpose checkout command. Even so, many repositories and tutorials still use checkout, so understanding it remains useful.
Common Pitfalls
The biggest pitfall is using git reset --hard when you only meant to unstage files or undo a commit while keeping the work. --hard overwrites the working tree and can destroy uncommitted changes.
Another mistake is thinking git checkout some-old-commit rewrites branch history. It does not. It places you in a detached HEAD state, where you are looking at an old commit without moving the branch itself.
People also confuse git reset file with git checkout file. The first unstages a file from the index. The second replaces the file content in the working tree with a version from Git history. Those are very different outcomes.
Finally, many users reach for checkout for everything because older tutorials teach it that way. In modern Git, switch and restore are usually clearer and less error-prone.
Summary
- '
git resetmainly movesHEADand can also change the index and working tree.' - '
git checkoutmainly changes what is checked out in the working tree or switches branches.' - '
git reset --soft,--mixed, and--harddiffer in how much state they rewrite.' - '
git checkoutdoes not normally rewrite branch history.' - Prefer
git switchandgit restorein newer workflows when their intent matches your task.

