Git reset refresher
21 Jun 2017git reset
is a confusing command, it is used for several different things in
Git, and sometimes they seem unrelated.
git reset file.txt
unstages file.txtgit reset --hard HEAD~
deletes the current commit
I've often come back to this article, which explains in detail how it works - I strongly recommend reading it. What follows is a short summary that makes sense to me, maybe it will help you as well.
It basically comes down to this:
Overview
Command | move branch | unstage changes | discard changes |
---|---|---|---|
git reset --soft |
✅ | ||
git reset --mixed |
✅ | ✅ | |
git reset --hard |
✅ | ✅ | ✅ |
git reset -- |
✅ |
Defaults
- Running
git reset <ref>
is the same as runninggit reset --mixed <ref>
(ref
could be a branch name or a commit sha) - Running
git reset <path>
is the same as runninggit reset -- <path>
Summary
git reset
works in three steps, on the three "trees" relevant to working with git:
- The ref (your current branch)
- The index (added/staged changes)
- The working directory (local changes to files)
Based on the mode (--soft
/--mixed
/--hard
), it will go through this list,
starting with changing where the current branch points, then updating the index
to match, then discarding local changes and cleanly checking that out.
When provided a file argument, optionally separated by --
, it skips the first
step, since it doesn't make sense to point an entire branch to changes of
specific files.
Differences from checkout
It seems like there should be a row that only has a check mark in the last column, what if you only want to discard your local changes without touching anything else? That's done with git checkout -- <path>
, or simply git checkout <path>
.
But wait, git checkout <ref>
also moves something, right?
Yes, checkout
moves the HEAD
, as opposed to reset
which moves the branch that HEAD
points to. You can think of moving HEAD
as simply turning your head to look at a different box of stuff, and moving the ref as actually ripping off the label from that box and placing it on a different box.