1

What is the difference in the actual effect of the following two commands? Don't they both make the staging area and the working directory to match the latest commit?

git reset --hard

git checkout <sha-of-latest-commit>

pkaramol
  • 16,451
  • 43
  • 149
  • 324

2 Answers2

2

git reset --hard discards all changes to files in worktree.

git checkout <sha-of-latest-commit> preserves those changes.

There is another difference in case when your HEAD references a branch (NOT a detached HEAD mode).

git checkout <sha-of-latest-commit> will detach HEAD.

git reset --hard will not detach HEAD.

Victor Yarema
  • 1,183
  • 13
  • 15
0

git reset --hard is equivalent to git reset --hard HEAD, i.e. it makes your branch point to HEAD (i.e. a NOP) and also resets both the index and the working tree to the same content.

git checkout with a literal sha1 will enter detached-head-mode, i.e. you will be no longer on your branch. It also does not change working tree or index.

See for yourself:

$ git init
$ touch a b
$ git add .
$ git commit -m 1
$ echo 1 >a; echo 1 >b; git add a #do some changes
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   a

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   b

$ git reset --hard 
$ git status # still on master, changes are gone
On branch master
nothing to commit, working directory clean
$ echo 1 >a; echo 1 >b; git add a  #redo changes
$ git checkout HEAD@{0}
$ git status  #no longer on master, changes are still there
HEAD detached at be924ba
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   a

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   b
michas
  • 25,361
  • 15
  • 76
  • 121
  • 1
    *It also does not change working tree or index.* Not true. – jub0bs Jan 02 '15 at 15:53
  • Could you explain, please? I gave a detailed example above showing no change on index and working tree. (Unless you specify an explicit path.) – michas Jan 02 '15 at 15:56