git-reset hash
sets the branch reference to the given hash, and optionally checks it out, with--hard
.
git-checkout hash
sets the working tree to the given hash; and unless hash is a branch name, you'll end up with a detached head.
ultimately, git deals with 3 things:
working tree (your code)
-------------------------------------------------------------------------
index/staging-area
-------------------------------------------------------------------------
repository (bunch of commits, trees, branch names, etc)
git-checkout
by default just updates the index and the working tree, and can optionally update something in the repository (with the -b
option)
git-reset
by default just updates the repository and the index, and optionally the working tree (with the --hard
option)
You can think of the repository like this:
HEAD -> master
refs:
master -> sha_of_commit_X
dev -> sha_of_commit_Y
objects: (addressed by sha1)
sha_of_commit_X, sha_of_commit_Y, sha_of_commit_Z, sha_of_commit_A ....
git-reset
manipulates what the branch references point to.
Suppose your history looks like this:
T--S--R--Q [master][dev]
/
A--B--C--D--E--F--G [topic1]
\
Z--Y--X--W [topic2][topic3]
Keep in mind that branches are just names that advance automatically when you commit.
So you have the following branches:
master -> Q
dev -> Q
topic1 -> G
topic2 -> W
topic3 -> W
And your current branch is topic2
, that is, the HEAD points to topic2.
HEAD -> topic2
Then, git reset X
will reset the name topic2
to point to X; meaning if you make a commit P on branch topic2, things will look like this:
T--S--R--Q [master][dev]
/
A--B--C--D--E--F--G [topic1]
\
Z--Y--X--W [topic3]
\
P [topic2]