1.2 Git Basics: Reset
In this lesson, I’ll explain Git reset. You’ll see how to use each kind of reset and how these varieties interact with the three Git trees.
- soft: only changes HEAD, but doesn’t change staged files in index or working files
- mixed: moves HEAD and updates the index with the contents of the revision to which HEAD now points
- hard: moves HEAD and updates the index and working directory—this is the only version of reset that can cause data loss
I’ll also show you how to use
git reset on individual files.
1.2 Git Basics: Reset
Git Reset. What does it do? It's how you undo some changes to the local to your computer. When you have done some work that you need to rewind, Reset is your friend. You can just start over, you can jump back and forth between the contents of various commits and do a bit of time traveling. You have a few options at your disposal with Git Reset. You can go hard, soft, and mixed. Plus you can operate on a whole commit object or at an individual file level. Each of these Reset variations affect specific trees, which Git uses to handle your files and its contents. Metaphorically speaking, every Reset option changes a different tree at different part of how Git saves snapshots. Trees, what are we talking about here? Git uses the working directory, the index, also known as the staging area, and something called head for creating and for retrieving commits. Your working directory lets you change files, and you can stage into the index. This staging area lets you fine tune and select what you want to put into your next commit. A commit object is a cryptographically hashed version of your contents. It has some added metadata and points back to previous commits, which lets us do our time traveling bits. Head is a reference that points to such commit objects. It is merely a pointer that updates with every new commit or change of branch. You can move it around and target any point in time with the commit object. For more info about trees and such, have a look at my video about the three trees in Git. It covers the basic workflow in Git and is a solid basis to better understand the logic of using Git Reset. git reset --hard. This goes the whole nine yards. And you will first move head, update the index with the contents of the commit head is not pointing at, and update the working directory with the contents of the index. And thereby possibly destroying content you changed in the working directory. Therefore, is the only version of Git Reset that is a bit dangerous if you don't know what you are doing. git reset --mixed, this will move head and also update the index with the contents of the desired commit that head is not pointing at. The working directory is unaffected by that operation. The mixed option is a default if you don't provide git reset with an option. It is always working directory safe, so no need to be afraid to lose your work. git reset --soft. This option will only move head and stops right there. In effect, this will undo the last git commit command. The working directory and files that might be staged are still unaffected by that operation. With all these options for git reset, you specifically tell git where to stop, replaying, rewinding the contents and files from previous commits, to specify the trees you want to affect. We can take the and provide reset with a file path. If you use a path, git won't move head. Why? Because head points to a commit object, and it cannot point to only a subset of that. In other words, head does not point to specific files, but to commit objects which consist of blocked files and some metadata. The index and working directory, on the other hand, can be addressed in slices of sorts. Only the index and working directory play a role when you use a path. It simply copies the contents of a file into the index. And it cannot do much else. Git reset, some-file name assumes that, by default, you meant git reset --mixed HEAD some-file name. And won't affect the working directory. By the way, because head cannot move, a soft option would be pointless. Let's say you've been working on version number 3 of a file, and added it to the index for the next commit. Now you want to unstage these changes. Run git reset some-file name to unstage that particular file. As a result, the index will be populated by the state of your file from version 2, the version from your last commit. The commit head is pointing at the changes you made in your file, version three, basically, is still available in the working directory. You're still able to get at these changes to stage version 3 of this file. So what you do in affect with git reset some-file name is you only manipulate the index. What about git reset --hard with some-file name? Why can't we use that as well? This functionality is accomplished by git checkout with a filename. git checkout some-file name is actually what git reset --hard some-file name would do. But git doesn't let us use the --hard option. Let's take this another step further. We can target any commit to reset a specific file, not just the most recent one, represented by head. This resets the targeted files in the index through a state of a certain commit, again without affecting the working directory or any commit. After you have reset, the index to the state of a certain commit a backwards update of sorts. You can use git checkout with a file name to check out the contents of the index into your working directory. Why use checkout? Because git reset --hard with a file is not something git lets you do. But be careful, using git checkout with a file path will get rid of your newest changes in your working directory and replaces it with the version of the file in that specific commit.