Git basics: checkout vs. reset
Today I got a better understanding of how git works, in particular what
git checkout and
git reset do.
- A commit holds a certain state of a directory and a pointer to its antecedent commit.
- A commit is identified by a so-called
reflooking something like
HEADis a pointer that is always pointing at the commit you are currently working on. Usually, it is pointing to a branch which is pointing to that commit.
- Branches are nothing but pointers to commits. You are 'on a branch' when
HEADis pointing to a branch.
git checkout <commit> <paths> tells git to replace the current state of
paths with their state in the given commit.
pathscan be files or directories.
- If no branch (or commit hash, see basic facts) is given, git assumes the
git checkout <path>restores
pathfrom your last commit. It is a 'filesystem-undo'.
- If no
pathis given, git moves
HEADto the given
commit(thereby changing the commit you're sitting and working on).
git checkout branchmeans switching branches.
git checkout HEAD~2 app/models/foo.rbdrops all modifications of
foo.rband replaces the file with its version two commits ago.
git reset <commit> re-sets the current pointer to the given
- If you are on a branch (you should usually be),
HEADand this branch are moved to
- If you are in
git resetdoes only move
HEAD. To reset a branch, first check it out.
Example: You are currently working upon commit
123abc. After resetting to a previous commit
git reset HEAD~2), you have no easy access to commit
HEADand the branch are both pointing to
To move the branch pointer 'back to the front', you can't use
git checkout, as it only moves
HEAD. You have to reset your branch to that commit:
git reset 123abc. (If you didn't save the first commit's hash (
git reflogwill help you finding it.)