Git Revert and Reset
Understand how to revert (undo) changes made in commits using 'git revert'. Learn the different types of reset (soft, mixed, hard) and their effects using 'git reset'.
Git Reset - Mixed Mode
The git reset
command is a powerful tool in Git that allows you to move the current branch's HEAD to a specified commit. It has different modes of operation that affect the staging area (index) and the working directory. The --mixed
mode is the default if no mode is specified. This means that when you just type git reset <commit>
, you're implicitly using git reset --mixed <commit>
.
Understanding Git Reset --Mixed (The Default Mode)
git reset --mixed
affects three areas:
- The HEAD: This is the pointer to the current commit on your branch.
git reset
always moves the HEAD to the specified commit. - The Staging Area (Index): This is where you prepare changes to be committed.
git reset --mixed
*removes* the changes from the staging area that were introduced in commits after the specified commit. - The Working Directory: This is where your actual files reside.
git reset --mixed
*does not* modify the files in your working directory. They remain as they were.
Detailed Explanation of 'git reset --mixed' and its Effects
Let's break down the effects of git reset --mixed
with a scenario:
Imagine you have a repository with the following commits:
A -> B -> C -> D (HEAD is currently pointing to D)
You then run the command:
git reset --mixed B
Here's what happens:
- HEAD Movement: The HEAD is moved from commit
D
to commitB
. This means your branch now points to commitB
. - Staging Area Update: The staging area is updated to reflect the state of commit
B
. Any files that were added, modified, or removed in commitsC
andD
are *removed* from the staging area. These changes are now considered "unstaged changes." - Working Directory: The files in your working directory remain unchanged. They still contain all the changes from commits
C
andD
. However, since those changes are not staged, Git sees them as modifications to the state of commitB
.
In summary: git reset --mixed
essentially "undoes" the commits after the specified commit, but keeps the changes in your working directory. This allows you to then selectively stage and commit those changes in a different way if desired.
Example
Let's say you have a file named my_file.txt
and have made the following changes:
- Commit A: Added the initial version of
my_file.txt
. - Commit B: Added a line "This is line 1." to
my_file.txt
. - Commit C: Added a line "This is line 2." to
my_file.txt
.
You now decide that commit C was a mistake, but you still want to keep the changes you made in commit C. You would use:
git reset --mixed B
After running this command:
- HEAD now points to commit B.
- The staging area now reflects the state of commit B (
my_file.txt
only contains "This is line 1."). - Your working directory still contains
my_file.txt
with the content "This is line 1.\nThis is line 2.".
You can now decide what to do with the "This is line 2." change. You can stage it again and create a new commit, modify it further, or even discard it entirely.
Key Takeaways
git reset --mixed
is the default reset mode.- It moves the HEAD to the specified commit.
- It unstages changes from commits that were "undone" (the staging area is reset to reflect the specified commit).
- It *does not* modify the files in your working directory.
- It's useful for undoing commits while keeping the changes for further modification or re-committing.