سؤال

Setup

Let's imagine a simple repository as follows. One can see that HEAD points at master

$ git log --decorate --graph
* commit 99d20608088ba9c74b57e36a1b0b79ff2be42d68 (HEAD, master)
| Author: Saaman <user@domain.com>
| Date:   Wed Apr 17 16:53:50 2013 +0200
|
|     My third commit
|
* commit a4a040c8b5c3923a2ba0f652caae0540f84c4c98
| Author: Saaman <user@domain.com>
| Date:   Wed Apr 17 16:53:27 2013 +0200
|
|     My second commit
|
* commit c5d20f203c11acbb9238ab77581e27a15ccde25e
  Author: Saaman <user@domain.com>
  Date:   Wed Apr 17 16:52:58 2013 +0200

      My first commit

$ git reflog
99d2060 HEAD@{0}: commit: My third commit
a4a040c HEAD@{1}: commit: My second commit
c5d20f2 HEAD@{2}: commit (initial): My first commit

Act

Now, let's perform some checkout operations

$ git checkout master
Already on 'master'

$ git reflog
99d2060 HEAD@{0}: checkout: moving from master to master
99d2060 HEAD@{1}: commit: My third commit
a4a040c HEAD@{2}: commit: My second commit
c5d20f2 HEAD@{3}: commit (initial): My first commit

$ git checkout HEAD

$ git reflog
99d2060 HEAD@{0}: checkout: moving from master to master
99d2060 HEAD@{1}: commit: My third commit
a4a040c HEAD@{2}: commit: My second commit
c5d20f2 HEAD@{3}: commit (initial): My first commit

The reflog shows that

  • Checking out HEAD doesn't produce any entry in the reflog
  • Checking out master inserts a new entry in the reflog (stating that HEAD moved from master to master)

Let's try something else

$ git checkout head
Note: checking out 'head'.

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

HEAD is now at 99d2060... My third commit

$ git reflog
99d2060 HEAD@{0}: checkout: moving from master to head
99d2060 HEAD@{1}: checkout: moving from master to master
99d2060 HEAD@{2}: commit: My third commit
a4a040c HEAD@{3}: commit: My second commit
c5d20f2 HEAD@{4}: commit (initial): My first commit

The reflog now shows

  • head has been resolved to the same SHA 99d2060
  • HEAD is now detached
  • A new entry has been inserted into the reflog (stating that HEAD moved from master to head)

Questions

I'm having a hard time understanding these behaviors.

  • Why does checking out HEAD does not produce anything in the reflog whereas checking out master (the branch pointing at by HEAD) does?
  • Why does checking out head (in lowercase) detaches the HEAD whereas git can successfully peel it to the same commit?

Note: These tests have been performed on Windows/msysgit

هل كانت مفيدة؟

المحلول

After analysing the code, here are some pieces of answer :

  • git checkout HEAD doesn't log anything whether the HEAD is detached or not.
  • moving from "master" to "master" is not really a useful information as neither the branch, nor its target are changed. A bit of a useless information to fill the log with, but quite harmless.
  • git checkout head doesn't work on Linux. It only works on Windows because the file system is case insensitive.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top