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]