10

Let's say I want to undo all changes introduced by previous commits.

As far as I understand, git reset --hard <specified commit> will remove all commits up until the specified commit, and undo all changes.
On the other hand git checkout <specified commit> will change my directory to reflect the specified commit.

So if I git reset after git checkout will it have the same result as git reset --hard?

Alternatively, if I simply git commit after git checkout, will the newly created commit overwrite the existing commits?

Atlas23250
  • 177
  • 2
  • 9

2 Answers2

12

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.

Géry Ogam
  • 6,336
  • 4
  • 38
  • 67
mik01aj
  • 11,928
  • 15
  • 76
  • 119
3

So if I git reset after git checkout will it have the same result as git reset --hard?

No. git reset (with --hard, or any other option) resets the HEAD, so you always lose commits, unless you are not specifying any commit to reset to.

After you do git checkout <commit> you are in a detached HEAD state, so git reset is a bit pointless because you won't be resetting any branch.

Alternatively, if I simply git commit after git checkout, will the newly created commit overwrite the existing commits?

No. Because again, you are in a detached HEAD state. You are essentially creating commits in a ghost branch.

The safest thing is to always create a new branch with git checkout -b and once you are sure you want to reset your other branch, then do git reset --hard.

FelipeC
  • 9,123
  • 4
  • 44
  • 38