6

Let's begin with a situation.

  1. I stash some changes (5 files) git stash
  2. Change some files
  3. Commit the changes git commit -m "Commit message"
  4. Get the changes back from stash git stash apply

I receive a merge-conflict in 2 files because of the commit. I no longer want the changes in those 2 files So I tried to revert those changes.

I did git checkout -- background.js

It failed with error

error: path 'src/background/background.js' is unmerged

But then I read this SO post and tried

git checkout HEAD -- background.js

It works successfully. It happened with me for both the files. I want to understand the difference bewteen

git checkout -- file AND git checkout HEAD -- file

Community
  • 1
  • 1
Sachin Jain
  • 21,353
  • 33
  • 103
  • 168

1 Answers1

4

Normally there isn't much of a difference. The key is that you had conflicts to resolve. From the man pages http://csurs.csr.uky.edu/cgi-bin/man/man2html?1+git-checkout

git checkout [--patch] [] [--] ...

...

The index may contain unmerged entries because of a previous failed merge. By default, if you try to check out such an entry from the index, the checkout operation will fail and nothing will be checked out. Using -f will ignore these unmerged entries. The contents from a specific side of the merge can be checked out of the index by using --ours or --theirs. With -m, changes made to the working tree file can be discarded to re-create the original conflicted merge result.

You were using checkout this way when it was failing. So by design, the checkout will fail due to the unmerged changes (not resolving the conflicts). Adding the HEAD told git which "branch" to use and so will actually checkout the file.

HEAD refers to the specific SHA that you are at in your repo. So you are telling git where to pull the files from in the same way that you would for a different branch.

Schleis
  • 41,516
  • 7
  • 68
  • 87
  • 6
    @blunderboy, in short: `git checkout -- ` checks out the contents known as `` *from the index,* while `git checkout HEAD -- ` checks it out from a specific commit to which the ref `HEAD` resolves (in 90% of cases it's the tip commit of your currently checked out branch). – kostix Mar 25 '14 at 17:25
  • @kostix I think you should add it as an answer. Simple, straight and to the point. And please write 1-2 lines about git's index as well in your answer to make it more complete.I like it. – Sachin Jain Mar 25 '14 at 17:26
  • @blunderboy, no, I'm fine with the accepted answer because expanding on *why* the first form didn't work for you is also important. Hence I just wanted to add a TL;DR-style footer ;-) Good job, Schleis. – kostix Mar 25 '14 at 17:32
  • @kostix I was not gonna change the accepted answer ;-) I just wanted TL;DR story to be more visible for wider audience (future readers)..Anyway its fine :) Thanks a lot for the useful comment – Sachin Jain Mar 25 '14 at 17:34
  • @blunderboy, if you want the concept of the index explained, start [here](http://stackoverflow.com/a/22178579/720999) or with any good book on the subject. – kostix Mar 25 '14 at 17:34
  • @blunderboy is correct - the problem isn't that there are conflicts, per se, the problem is that having conflicts prevent checking out the version in the index, since there *is* no version in the index. – Edward Thomson Mar 25 '14 at 20:46
  • @EdwardThomson: More precisely, there are *too many* versions in the index (up to 3 during a conflicted merge: "base", "ours", and "theirs"). But you can name any one of the three using `::path`, e.g., `:1:background.js` is the base version. See gitrevisions(7). `git checkout` also has `--ours` and `--theirs` options to name versions 2 and 3. – torek Mar 25 '14 at 21:02