Commits are trees, branches are pointers to some commits, and HEAD
(alias: @
) is a pointer to some branch or to some commit (‘detached HEAD
’).
git checkout <commit>
moves the HEAD
, index, and working tree to the specified commit, and keeps any local changes in the index and working tree if possible, otherwise the operation is aborted. When you do this, the HEAD
becomes detached. You will see this message, which is pretty self-explanatory:
You are in 'detached HEAD' state. You can look around, make
experimental changes and commit them, and you can discard any commits
you make in this state without impacting any branches by performing
another checkout.
If you want to create a new branch to retain commits you create, you
may do so (now or later) by using -b with the checkout command again.
Example:
git checkout -b new_branch_name
So you will not loose any changes in the working tree and index, and you will not loose any commits with it.* It is a safe operation.
git reset --hard <commit>
moves the branch pointed to by HEAD
or the HEAD
if it is detached, index, and working tree to the specified commit. So you will loose all the changes in the working tree and index. Additionally, if you're moving to some older commit and the newer commits are not in some other branch, you will loose these newer commits too. It is not a safe operation so don't do this unless you really understand what you're doing.
See also these great answers for information about how to undo a commit.
You might also benefit from using a GUI tool like SourceTree.
* Well, unless you're already in detached HEAD
state on some dangling commit, but normally you shouldn't worry.