7

I tried the following out of curiosity:

git checkout head

And I got this:

$ git checkout head
Note: checking out 'head'.
You are in 'detached HEAD' state.

Me@MyPC /c/repo ((9da1bd7...))
$

Whereas

git checkout HEAD

does nothing (as expected). So what exactly is the former command doing?

More info: Yes, I am on Windows. And it did not create a tag or a branch as far as I can tell:

Me@MyPC /c/repo ((9da1bd7...))
$ git log -n 1
commit 9da1bd740434923ae55ca1b50efb7c62eb6e0c35
Author: someone else
Date:   Fri Dec 6 15:44:08 2013 +0100

Me@MyPC /c/repo ((9da1bd7...))
$ git tag -l
TestRelease

Me@MyPC /c/repo ((9da1bd7...))
$ git branch -l
* (detached from head)
  master
DasKrümelmonster
  • 5,816
  • 1
  • 24
  • 45
  • 1
    See [this answer](http://stackoverflow.com/questions/2304087/what-is-git-head-exactly/4381549#4381549) to a similar question. – Digital Chris Dec 19 '13 at 14:02
  • I advise to use `gitk`. There is no need to do everything from command line. `Gitk` is great for checkouts. – Val Dec 19 '13 at 14:13

2 Answers2

6

At https://github.com/git/git/blob/ad7044857660af7ffaaf8fbbccc77b817d1b938f/builtin/checkout.c#L624 the string "HEAD" is special-cased as a no-op, with a strcmp (case-sensitive). Elsewhere in the git system, something parses the argument to checkout case-insensitively (or looks it up as a filename, making it possibly case-insensitive depending on the filesystem).

  • 1
    I don't think it's in git, I think it's in the file system. The OP is on Windows, which uses a case insensitive file system, and HEAD is stored as a regular file named "HEAD", so on Windows, looking for "head" will produce a match. –  Dec 19 '13 at 14:24
  • Ah yes, my test was on cygwin too. Anyway, the case-sensitive special case explains why `HEAD` in all caps behaves differently. Answer updated. –  Dec 19 '13 at 14:28
  • So it does checkout HEAD, but because the comparison to "HEAD" fails, it thinks this is another branch. Consequently the repo is set to detached HEAD state and I receive a warning? – DasKrümelmonster Dec 19 '13 at 14:55
  • 2
    Right... you asked for `head` so it looks for `.git/head` (among other things) and succeeds because `.git/HEAD` exists and Windows can't tell the difference. Then git thinks it has successfully opened a file that is *not* called "HEAD", and also is not a branch (because it wasn't found in `.git/refs/heads`) so it treats it the same as any other non-special non-branch checkout. –  Dec 19 '13 at 15:44
1

From what you pointed out. I would think that you have a head tag which is pointing on the non latest commit in the branch you're currently in.

I tried doing what you did on a clean repo (tested on Ubuntu), and it complained about the non existing branch head.

$git init  
$git checkout head
head error: pathspec 'head' did not match any file(s) known to git.
TheMeaningfulEngineer
  • 15,679
  • 27
  • 85
  • 143
  • As git says "You are in 'detached HEAD' state." I think it is a tag and not a branch. This can be checked with this command `git tag -l head` : if it displays `head` there is a tag named head. – Fredszaq Dec 19 '13 at 14:22
  • "A branch that does not point to the latest commit on that branch" makes no sense, unless I'm really misunderstanding what you're trying to say. –  Dec 19 '13 at 14:25
  • You are right, this was meaningless. Thanks for pointing it out. – TheMeaningfulEngineer Dec 19 '13 at 14:34