What is HEAD in Git?

后端 未结 22 1957
野的像风
野的像风 2020-11-22 10:02

You see the Git documentation saying things like

The branch must be fully merged in HEAD.

But what is Git HEAD exac

相关标签:
22条回答
  • 2020-11-22 10:53

    You can think of the HEAD as the "current branch". When you switch branches with git checkout, the HEAD revision changes to point to the tip of the new branch.

    You can see what HEAD points to by doing:

    cat .git/HEAD
    

    In my case, the output is:

    $ cat .git/HEAD
    ref: refs/heads/master
    

    It is possible for HEAD to refer to a specific revision that is not associated with a branch name. This situation is called a detached HEAD.

    0 讨论(0)
  • 2020-11-22 10:55

    A great way to drive home the point made in the correct answers is to run git reflog HEAD, you get a history of all of the places HEAD has pointed.

    0 讨论(0)
  • 2020-11-22 10:57

    I recommend this definition from github developer Scott Chacon [video reference]:

    Head is your current branch. It is a symbolic reference. It is a reference to a branch. You always have HEAD, but HEAD will be pointing to one of these other pointers, to one of the branches that you're on. It is the parent of your next commit. It is what should be what was last checked-out into your working directory... This is the last known state of what your working directory was.

    The whole video will give a fair introduction to the whole git system so I also recommend you to watch it all if have the time to.

    0 讨论(0)
  • 2020-11-22 10:58

    There is a, perhaps subtle, but important misconception in a number these answers. I thought I'd add my answer to clear it up.

    What is HEAD?

    HEAD is YOU

    HEADis a symbolic reference pointing to wherever you are in your commit history. It follows you wherever you go, whatever you do, like a shadow. If you make a commit, HEAD will move. If you checkout something, HEAD will move. Whatever you do, if you have moved somewhere new in your commit history, HEAD has moved along with you. To address one common misconception: you cannot detach yourself from HEAD. That is not what a detached HEAD state is. If you ever find yourself thinking: "oh no, i'm in detached HEAD state! I've lost my HEAD!" Remember, it's your HEAD. HEAD is you. You haven't detached from the HEAD, you and your HEAD have detached from something else.

    What can HEAD attach to?

    HEAD can point to a commit, yes, but typically it does not. Let me say that again. Typically HEAD does not point to a commit. It points to a branch reference. It is attached to that branch, and when you do certain things (e.g., commit or reset), the attached branch will move along with HEAD. You can see what it is pointing to by looking under the hood.

    cat .git/HEAD
    

    Normally you'll get something like this:

    ref: refs/heads/master
    

    Sometimes you'll get something like this:

    a3c485d9688e3c6bc14b06ca1529f0e78edd3f86
    

    That's what happens when HEAD points directly to a commit. This is called a detached HEAD, because HEAD is pointing to something other than a branch reference. If you make a commit in this state, master, no longer being attached to HEAD, will no longer move along with you. It does not matter where that commit is. You could be on the same commit as your master branch, but if HEAD is pointing to the commit rather than the branch, it is detached and a new commit will not be associated with a branch reference.

    You can look at this graphically if you try the following exercise. From a git repository, run this. You'll get something slightly different, but they key bits will be there. When it is time to checkout the commit directly, just use whatever abbreviated hash you get from the first output (here it is a3c485d).

    git checkout master
    git log --pretty=format:"%h:  %d" -1
    # a3c485d:   (HEAD -> master)
    
    git checkout a3c485d -q # (-q is for dramatic effect)
    git log --pretty=format:"%h:  %d" -1   
    # a3c485d:   (HEAD, master)
    

    OK, so there is a small difference in the output here. Checking out the commit directly (instead of the branch) gives us a comma instead of an arrow. What do you think, are we in a detached HEAD state? HEAD is still referring to a specific revision that is associated with a branch name. We're still on the master branch, aren't we?

    Now try:

    git status
    # HEAD detached at a3c485d
    

    Nope. We're in 'detached HEAD' state.

    You can see the same representation of (HEAD -> branch) vs. (HEAD, branch) with git log -1.

    In conclusion

    HEAD is you. It points to whatever you checked out, wherever you are. Typically that is not a commit, it is a branch. If HEAD does point to a commit (or tag), even if it's the same commit (or tag) that a branch also points to, you (and HEAD) have been detached from that branch. Since you don't have a branch attached to you, the branch won't follow along with you as you make new commits. HEAD, however, will.

    0 讨论(0)
提交回复
热议问题