What is git reset
?
git reset
is a powerful and versatile command used to revert a Git repository’s state to a specific commit. Its primary function is to move the HEAD
pointer of a branch to a previous commit. However, the impact of reset
on the index (Staging Area) and the working directory varies significantly depending on the option used, so it is crucial to understand the differences between each option.
First, you need to understand Git’s three state areas:
- Working Directory: The actual files you are currently working on.
- Index / Staging Area: A list of changes that will be included in the next commit.
- HEAD: The last commit that the current branch points to.
The Three Options of git reset
The core of git reset
is deciding how far back to revert among these three areas.
1. git reset --soft <commit>
The --soft
option is the most conservative reset. This command moves only the HEAD
pointer to the specified commit. It does not touch the index or the working directory at all.
- Action: Moves
HEAD
to<commit>
. - Result:
- The commit that
HEAD
points to is changed. - The index (Staging Area) remains unchanged. This means all changes between the original
HEAD
and<commit>
are left in a staged state. - The files in the working directory are not changed at all.
- The commit that
- Primary Use Case: Useful for squashing multiple commits into one. For example, if you want to undo the last three commits and re-create them as a single commit, you can run
git reset --soft HEAD~3
. All the changes from the last three commits will be ready in the staging area.
Command Example:
# Undo the last commit, but keep the changes staged.
git reset --soft HEAD~
2. git reset --mixed <commit>
(Default Option)
--mixed
is the default option for git reset
. If you run the reset
command without any options, it will behave as --mixed
. This option reverts HEAD
and the index to the state of the specified commit.
- Action: Reverts
HEAD
and the index to the state of<commit>
. - Result:
- The commit that
HEAD
points to is changed. - The index is reset to the state of
<commit>
. This means all staged changes are unstaged and moved to the working directory. - The files in the working directory are not changed.
- The commit that
- Primary Use Case: Used when you want to undo a commit but keep the file changes. It is useful for modifying staged content or re-staging only some of the changes.
Command Example:
# Undo the last commit and leave the changes only in the working directory (unstaged).
git reset --mixed HEAD~ # Same as `git reset HEAD~`
3. git reset --hard <commit>
--hard
is the most powerful and destructive option. This command reverts HEAD
, the index, and even the working directory to the state of the specified commit.
- Action: Reverts
HEAD
, the index, and the working directory to the state of<commit>
. - Result:
- The commit that
HEAD
points to is changed. - The index is reset to the state of
<commit>
. - All changes in the working directory are permanently deleted. Any work done since
<commit>
will be lost, so extreme caution is required when using this option.
- The commit that
- Primary Use Case: Used when you want to completely discard all recent changes (commits, staging, and working directory changes) and return to a clean state at a specific point in time.
Command Example:
# Completely delete all changes related to the last commit (including staging and working directory content).
git reset --hard HEAD~
Summary
Option | HEAD (Branch Pointer) |
Index (Staging Area) | Working Directory (Files) | Primary Use |
---|---|---|---|---|
--soft |
Moves (Yes) | No Change (No) | No Change (No) | Squashing commits (all changes remain staged) |
--mixed |
Moves (Yes) | Resets (Yes) | No Change (No) | Undoing a commit and modifying staging (changes preserved) |
--hard |
Moves (Yes) | Resets (Yes) | Resets (Yes) | Completely discarding all changes |
Caution
git reset
is an operation that changes the local repository’s commit history. If you reset a commit that has already been pushed to a remote repository, you will need the--force
option to push it again. This can cause conflicts with your teammates’ history, so it is safer to usegit revert
on shared branches.git reset --hard
is an irreversible operation, so it is a good idea to double-check your current status withgit status
orgit log
before running it.
Leave a comment