Undo a change with git reset (Git & Dev Tools)
Learn Undo a change with git reset (Git & Dev Tools) step by step with clear examples and exercises.
Why This Matters
Undoing changes is an essential part of any development workflow, and Git provides several ways to do this. In this lesson, we'll focus on using git reset to undo changes at the commit level. This is particularly useful when you've made a commit that you want to revert or when you need to move back to an earlier state in your project's history.
Understanding how to use git reset can help you maintain a clean and organized project history, making it easier to collaborate with others and track the evolution of your codebase. It also allows you to recover from mistakes or change your mind about certain decisions without losing valuable work.
Prerequisites
To follow along with this lesson, you'll need:
- A basic understanding of Git and its fundamental concepts, such as commits, branches, and merges. You should be familiar with creating, switching, and deleting branches, as well as making and committing changes.
- Familiarity with the command line or terminal. You should feel comfortable navigating your file system and running commands in a terminal.
- A local Git repository that contains at least one commit on a branch other than
master. This will allow you to practice moving between branches and undoing changes usinggit reset.
Core Concept
git reset is a versatile command that lets you move your current HEAD to a different commit, discard changes, or even revert specific files within a commit. It operates on three modes: --soft, --mixed, and --hard.
Soft Reset (git reset --soft )
A soft reset moves the HEAD to the specified commit while preserving all changes in the working directory and the staging area. This means that you can still access the changed files, but they won't be part of the next commit unless you explicitly add them using git add.
$ git reset --soft <commit>
Mixed Reset (default mode) (git reset )
A mixed reset moves the HEAD to the specified commit, discards changes in the working directory, but keeps them staged. This means that if you've made any changes since the last commit and haven't yet added them, those changes will be lost unless you use git add before running a soft reset.
$ git reset <commit>
Hard Reset (git reset --hard )
A hard reset moves the HEAD to the specified commit, discards changes in both the working directory and the staging area. This means that any changes you've made since the last commit will be permanently lost. Be very careful when using a hard reset, as it can lead to data loss if not used correctly.
$ git reset --hard <commit>
Worked Example
Let's walk through an example of using git reset to undo changes in a Git repository.
- Create a new Git repository and make some initial commits:
$ mkdir my-project && cd my-project
$ git init
$ touch readme.md
$ git add readme.md
$ git commit -m "Initial commit"
$ echo "This is a test change." >> readme.md
$ git status
- Create and checkout a new branch:
$ git checkout -b test-branch
Switched to a new branch 'test-branch'
- Make some changes on the
test-branchand stage them for commit:
$ echo "This is another test change." >> readme.md
$ git add readme.md
$ git status
- Realize that you want to revert these changes and move back to the initial commit on the
masterbranch:
$ git checkout master
Switched to branch 'master'
- To undo the changes made on
test-branch, we can use a soft reset. First, let's find the hash of the initial commit on themasterbranch:
$ git log --oneline
6f8e4d9 (HEAD -> master) Initial commit
2c0387b Test changes on test-branch
Now, we can use a soft reset to move our current HEAD back to the initial commit:
$ git reset --soft 6f8e4d9
HEAD is now at 6f8e4d9 Initial commit
By using git reset --soft, we moved the HEAD back to the initial commit (the one with the hash 6f8e4d9) and preserved our changes in both the working directory and the staging area. Now, if you check the contents of readme.md, you'll see that it matches the initial commit on the master branch.
Common Mistakes
- Forgotten arguments: Remember to include the correct arguments when using
git reset. For example, use--soft,--mixed, or--hardas needed.
- Moving too far back: Be careful not to move too far back in your project's history with a hard reset, as it can lead to data loss if you overwrite important commits.
- Not committing changes before resetting: If you have made changes since the last commit and haven't yet added them, using a mixed or hard reset will discard those changes permanently. Always commit your changes before resetting.
- Not specifying a commit hash: When using
git reset, it's essential to specify a commit hash or branch name. Failing to do so may result in an error or unintended consequences, such as moving the HEAD to an unexpected commit.
Practice Questions
- You've made some changes on the
masterbranch and want to revert to the previous commit while keeping those changes in the working directory. How can you achieve this usinggit reset?
To keep the changes in the working directory, use a soft reset:
$ git checkout <previous-commit> --soft
- You've created a new branch, made some changes, and now realize that you should have made those changes on the
masterbranch instead. How can you move your changes from the new branch to themasterbranch without losing any work?
First, merge the new branch into the master branch:
$ git checkout master
$ git merge <new-branch>
Then, use a hard reset on the master branch to move back to the commit before the merge:
$ git reset --hard HEAD~1
- You've accidentally deleted a file on the
masterbranch and want to revert to the previous commit where the file still exists. How can you achieve this usinggit reset?
First, find the hash of the commit where the file still exists:
$ git log --oneline
6f8e4d9 (HEAD -> master) Initial commit
2c0387b Test changes on test-branch
Then, use a soft reset to move your HEAD back to that commit:
$ git reset --soft 6f8e4d9
Now, the deleted file should be restored in your working directory.
FAQ
- What happens when I use
git reset --hardon my current branch?
When you use git reset --hard on your current branch, it moves the HEAD to the specified commit and discards any changes in both the working directory and the staging area. This means that any changes you've made since the last commit will be permanently lost. Be very careful when using a hard reset, as it can lead to data loss if not used correctly.
- Can I undo a merge commit with
git reset?
Yes, you can undo a merge commit with git reset, but it's recommended to use git revert instead because it creates a new commit that reverses the changes made by the original merge commit. This allows you to maintain a clear project history and makes it easier for others to understand what happened.
- What is the difference between
git reset --soft,--mixed, and--hard?
git reset --soft moves the HEAD to the specified commit while preserving all changes in the working directory and the staging area. This means that you can still access the changed files, but they won't be part of the next commit unless you explicitly add them using git add. A mixed reset moves the HEAD to the specified commit, discards changes in the working directory, but keeps them staged. A hard reset moves the HEAD to the specified commit, discards changes in both the working directory and the staging area. Be very careful when using a hard reset, as it can lead to data loss if not used correctly.
- What is the difference between
git resetandgit checkout?
git reset moves the HEAD of your current branch to another commit without modifying the working directory or staging area (unless you use the --soft, --mixed, or --hard options). In contrast, git checkout switches the active branch and updates both the working directory and the staging area to match the new branch. If you want to undo changes on your current branch without affecting other branches, use git reset. If you want to switch between branches while preserving your changes, use git checkout.
- What is the difference between
git resetandgit revert?
git reset moves the HEAD of your current branch to another commit and discards changes in the working directory or staging area (depending on the mode used). In contrast, git revert creates a new commit that reverses the changes made by an earlier commit. This allows you to maintain a clear project history and makes it easier for others to understand what happened. When using git reset, be careful not to overwrite important commits or discard valuable work. When using git revert, you can safely undo changes without worrying about data loss.