1302

You see the Git documentation saying things like

The branch must be fully merged in HEAD.

But what is Git HEAD exactly?

nbro
  • 15,395
  • 32
  • 113
  • 196
bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • 11
    See also http://stackoverflow.com/questions/964876/head-and-orig-head-in-git/967611#967611 – VonC Feb 20 '10 at 23:59
  • Also see [how to undo multiple commits using HEAD, or how to checkout to multiple commits before](https://stackoverflow.com/a/46350644/5175709) – mfaani Feb 07 '20 at 19:19
  • Curious that there's practically a 1:1 correspondence between 'heads' and (named) 'branches' (see [`git ls-remote`](https://git-scm.com/docs/git-ls-remote) as evidence) and yet the definition of 'HEAD' seems so hard to pin down. The documentation for [git branch](https://git-scm.com/docs/git-branch) says simply that `HEAD` is, in effect, "the tip of the current branch". All the confusion must actually be about the definition of a branch -- which is surprisingly nuanced: [What exactly do we mean by "branch"?](https://stackoverflow.com/q/25068543/86967) – Brent Bradburn Mar 26 '23 at 20:59
  • _HEAD names the commit on which you based the changes in the working tree_ source: [gitrevisions manual](https://git-scm.com/docs/gitrevisions) – David Balažic May 16 '23 at 14:00

27 Answers27

954

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.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 69
    So git HEAD is context dependent on which BRANCH you are on, correct? Even further, __you__ as a developer? I guess I'm asking, Is Git HEAD going to be a repository-wide global thing, or individual for each dev? – bobobobo Feb 20 '10 at 23:02
  • 124
    @bobobobo: That's right, HEAD is like a pointer that points to the current branch. When you checkout a different branch, HEAD changes to point to the new one. The current HEAD is local to each repository, and is therefore individual for each developer. – Greg Hewgill Feb 20 '10 at 23:04
  • So this should also explains why when one pushes revisions to a remote "central" repository, which doesn't have HEAD since it doesn't have a checked out working copy, he typically push the HEAD of the local repository to the master branch of the remote repository, right? – Meng Lu Dec 30 '11 at 18:27
  • 1
    I feel the ideas explained in this thread can be better illustrated by a graph of some sort ... any one? – Meng Lu Dec 30 '11 at 18:28
  • 3
    Besides `HEAD` being the current branch, **must it be the last commit** in the current branch? – nonopolarity Aug 30 '12 at 02:52
  • 82
    @動靜能量: HEAD can point to *any* commit, it does not need to be the last commit in any branch. (When HEAD points to a commit that is not the last commit in a branch, that is a "detached HEAD"). – Greg Hewgill Aug 30 '12 at 02:56
  • 6
    @GregHewgill This question should be updated to say "You can think of the HEAD as the 'current commit'" rather than the "current branch". This defition confused me when I found that during an interactive rebase with many commits, git updates `HEAD` but not the branch (as evidenced by `git reset --hard branchname`). It also explains why `git reflog HEAD` shows you all steps during rebases that contain many commits, whereas `git reflog branchname` shows you only one commit for the rebase. – Rose Perrone Mar 13 '13 at 18:29
  • 8
    Git HEAD is a pointer to a given commit, just like branch names, the only difference being that while branch names are conceptually meant to point to the latest commit in a branch, a HEAD can be used to hop between commits either within the same branch or across branches. You may also try to visualize HEAD as a mouse pointer, that lets you select a commit that you want to check out. – Ryan Jul 26 '13 at 19:37
  • 185
    HEAD is *not* "the current branch". Is is the name given to the commit from which the working tree's current state was initialized. In more practical terms, it can be thought of as a symbolic reference to the checked-out commit. – Ben Collins Dec 09 '13 at 07:25
  • 5
    @BenCollins Thank you. It's unfortunate that the accepted answer (above) gives an incorrect answer. – Fixee Jun 16 '14 at 14:16
  • 5
    @BenCollins Quoting from [Git Branching - What a Branch Is](http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is), concerning `HEAD`: _"In Git, this is a pointer to the local branch you’re currently on."_ Further, note that a branch itself is but a pointer. Quoting from the same source: _"A branch in Git is simply a lightweight movable pointer to [a commit]. (...) A branch in Git is in actuality a simple file that contains the 40 character SHA-1 checksum of the commit it points to."_ So I think the accepted answer is fine. Yours is also. Where's the difference? – Malte Skoruppa Jul 23 '14 at 15:20
  • 8
    @MalteSkoruppa the difference is that one doesn't have to be on a branch at all. The working copy can come from any commit, regardless of what branch you were on, in which case you'd be on a detached head. – Ben Collins Jul 23 '14 at 15:41
  • 1
    @BenCollins I agree, detached heads are a special case, but that case is also mentioned in the accepted answer. My point being, the accepted answer is perfectly fine. :) – Malte Skoruppa Jul 24 '14 at 09:59
  • 25
    Voted down. I agree with @BenCollins. In my opinion the first sentence is quite confusing, and could be rephrased to: "You can think of the HEAD as the current commit on the current branch" – dalvarezmartinez1 Sep 01 '14 at 15:20
  • 6
    @dalvarezmartinez1 - Absolutely.Also voted down. Git is complex enough to accept as correct some wrong answers. – SChepurin Sep 10 '14 at 13:35
  • 1
    @dalvarezmartinez1: how does "You can think of the HEAD as the current commit on the current branch" make any sense, given that a branch is a pointer / symbolic reference to an arbitrary commit? Are you using the word "branch" in the sense of some other VCS? – Don Hatch Jul 10 '15 at 02:43
  • 1
    @DonHatch "given that a branch is a pointer / symbolic reference to an arbitrary commit" hmmm I would say that, at least for me, for my understanding, it makes more sense for a branch to be a collection of commits, an array of commits. Then you have a pointer to this array, and a name, and more stuff, this results in a branch. Then you can navigate through this array (read through this branch), between different commits, by using the HEAD pointer, which points to the current commit, on the current branch (move it backwards with checkout and #SHA1, move one forwards with commit) – dalvarezmartinez1 Jul 23 '15 at 09:30
  • 2
    @dalvarezmartinez1: everything you say makes sense to me, but it is terminology used by other VCSs; git does not think that way, and in git terminology "branch" does not mean all the meaningful things you listed; it just means a reference to a commit. I *wish* git thought in the sensible way you are describing-- in my experience git makes it essentially impossible to examine the array of commits of which you speak-- it just doesn't remember that information. To me, this is a really serious failing of git. – Don Hatch Jul 24 '15 at 09:18
  • 1
    @DonHatch, perhaps you should learn to use the options of `git log` better. You can indeed view all the parent and ancestor commits of any given commit, and the options for sifting through this data to get what you need are powerful in the extreme. – Wildcard Feb 08 '16 at 23:38
  • @Wildcard - glad you're so happy with it, but despite all the powerful-in-the-extreme features of which you speak, it's lacking basic information that I, and many others, find indispensible. Take a look at the famous diagram on this page: http://nvie.com/posts/a-successful-git-branching-model/ . The style is often called "swim lanes" . Can you get such a drawing out of git? You definitely cannot; there's plenty of discussion of this fact around the web. That fact alone makes it difficult for many people coming from a perforce background to see git as a serious option. – Don Hatch Feb 11 '16 at 06:14
  • @DonHatch, I thought "Git Flow" looked like a great branching model until I read ["Git Flow Considered Harmful"](http://endoflineblog.com/gitflow-considered-harmful) and the [follow-up post](http://endoflineblog.com/follow-up-to-gitflow-considered-harmful). I find that workflow much more workable, personally. – Wildcard Feb 11 '16 at 19:29
  • @Wildcard - Thanks for the pointers. To be clear, I didn't mean to be advocating GitFlow (I guess that's the model being discussed in the article); I haven't looked at it too closely, nor at alternatives. But I'm definitely a big fan of diagrams with robust swim lanes, of which the diagrams in that article are a really good example, independent of the article's viewpoint. Using GitFlow or not, you can't make such diagrams out of the info that's normally in git. – Don Hatch Feb 11 '16 at 23:59
  • Is a revision a commit? – orrymr Apr 08 '16 at 06:06
  • Aside from `master` which is obvious. Can you explain what does `ref: refs/heads/master` refer to? Do we have multiple heads? – mfaani Sep 01 '16 at 06:30
  • You can use `git symbolic-ref --short HEAD` to output what branch HEAD is pointing at which is pretty useful to confirm whether or not you're in detached HEAD state or not – solstice333 Aug 03 '17 at 00:55
  • @BenCollins re `HEAD` is not the current branch, it is symbolic reference to the checked-out commit: in truth it is typically neither. It is a symbolic reference to whatever you've checked out. If it is a commit, yes, it points to the commit, but typically it is not. Similarly, OP, `HEAD` can refer to a commit that is associated with a branch name **and still be detached**. `HEAD` is only attached if it is **not** pointing to a commit, but rather to a branch. See [my answer](https://stackoverflow.com/a/54935492/7936744) – De Novo Feb 28 '19 at 22:49
  • 3
    Just to hammer it home: Greg (OP), re: "(When HEAD points to a commit that is not the last commit in a branch, that is a "detached HEAD")." Nope. If `HEAD` points directly to a commit, no matter what commit that is (even if it is the last commit in a branch), it is detached. – De Novo Feb 28 '19 at 23:00
  • @BenCollins "[HEAD] is the name given to the commit from which the working tree's current state was initialized." Not necessarily. It's typically true, but not always. For example, after `git reset --soft ` can point HEAD to a completely different snapshot, but doesn't change the state of the working tree. Or after a `git commit`, it would be more accurate to say the HEAD commit was initialized (indirectly) from the working tree's current state rather than vice versa. – LarsH Mar 01 '19 at 02:57
  • HEAD is just a pointer to commit id that you have checked out recently. If HEAD is on some older commit ids which are not referenced by name(say-branch/tag) then it is said to be in 'detached HEAD' state. – weber Jul 31 '19 at 04:05
  • I would love to see the uses of HEAD enlisted. I've always done `git clone ... && git remote set-head origin -d` so I never see this HEAD*! It's just an eyesore that keeps coming in the way when looking at the branch names in the commit history. *Of course, when I checkout a commit no branch is on, this detatched HEAD appears which is useful and then disappears the moment I'm back to the branch. Yet to learn about other conveniences of having HEAD around all the time. – trss Aug 20 '19 at 06:44
  • 1
    @trss it is mostly used as a "current branch" shortcut, "diff last 2 commits in my current branch" would be `git diff HEAD~2`. If you want to check out two commits back you don't need to `git log`, find the hash and `git checkout ` but only `git checkout HEAD~2` (which will also put you in 'detached HEAD' as well). – SidOfc Nov 11 '19 at 13:53
  • Thanks for the heads up on the commands referencing HEAD. Since they happen to work even when `git remote set-head origin -d` has made it disappear, I'm yet to see any other convenience of having the HEAD around all the time. – trss Sep 25 '20 at 17:08
  • The command `cat .git/HEAD` works fine in Unix/Linux/PowerShell. In a Windows command prompt you can use `type .git\HEAD` instead. – Morten Sep 12 '22 at 10:43
  • What else could be in this file? Are you curious to see other options? Is the commit hash to be the SIGN for understanding the HEAD is detached? I will not spoil it - try to write in this file `ref: refs/tags/tag-name` and see what happens in `git status` and what happens with the new commit. – Black Akula Nov 28 '22 at 18:29
  • https://git-scm.com/docs/git-diff states at several points that HEAD is basically "latest commit". All this nitpicking is useless, just like saying that dogs do not have 4 legs, because dogs with 3 or even 5 legs exist. In other words "the answer is technically correct, but useless". Comparing with HEAD compares with a specific commit (or maybe some other state), the fact that the .git/HEAD file only stores the branch name is irrelevant. – David Balažic Apr 26 '23 at 10:08
234

To quote other people:

A head is simply a reference to a commit object. Each head has a name (branch name or tag name, etc). By default, there is a head in every repository called master. A repository can contain any number of heads. At any given time, one head is selected as the “current head.” This head is aliased to HEAD, always in capitals".

Note this difference: a “head” (lowercase) refers to any one of the named heads in the repository; “HEAD” (uppercase) refers exclusively to the currently active head. This distinction is used frequently in Git documentation.

Another good source that quickly covers the inner workings of git (and therefore a better understanding of heads/HEAD) can be found here. References (ref:) or heads or branches can be considered like post-it notes stuck onto commits in the commit history. Usually they point to the tip of series of commits, but they can be moved around with git checkout or git reset etc.

nCardot
  • 5,992
  • 6
  • 47
  • 83
Silfheed
  • 11,585
  • 11
  • 55
  • 67
  • 1
    From this: "Each head has a name". And "one head is selected as the “current head.” This head is aliased to HEAD". So i conclude from this that "HEAD" does not refer to situation of "detached HEAD" state. – gxyd Dec 27 '15 at 10:00
  • 2
    @gxyd if it is the case that HEAD doesn't point to a 'head', it is a detached HEAD. It is pointing at the commit id of the commit you have specified (using, for example, `git checkout HEAD~2`), which is not the commit id of a known head. See the article at http://eagain.net/articles/git-for-computer-scientists/ for a more thorough explanation. – Silfheed Jan 05 '16 at 22:24
  • 3
    @Silfheed: Generally I think this answer is conceptually more sound than the accepted one (even though using lowercase "head" to refer to a branch confuses many people). However `git revert` isn't a good example of moving a branch to not be at the tip, because `git revert` just creates some new commits and still leaves the current branch at the (new) tip. – LarsH Mar 01 '19 at 03:06
  • 5
    "which is not the commit id of a known head" - Actually, a detached HEAD *can* be pointing at a commit ID which is also the commit ID of a known head (or several heads). What makes it detached is that the HEAD is pointing directly to the commit ID, not to a head. This will affect the behavior of future `commit`s, `reset`s, etc. – LarsH Mar 01 '19 at 03:08
  • 3
    @LarsH: Good point on a detached HEAD pointing at a commit ID instead of a reference. You can actually verify this by looking at .git/HEAD. If it is detached, it will contain the hash of a commit, even if it's the same commit as a known head. If it is attached, it will contain the path to the head (ie 'ref: refs/heads/bob'). As for the revert command, after 8 years I never caught that typo. Git reset is what allows you to adjust a particular head to point to a particular commit. – Silfheed Mar 01 '19 at 23:37
  • This answer is useful in noting the difference between _HEAD_ and _head_ but otherwise I find it a bit confusing. `HEAD` is simply a reference to a commit that will be the parent of the next commit you're going to create. – legends2k Apr 23 '19 at 05:36
133

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.

Community
  • 1
  • 1
De Novo
  • 7,120
  • 1
  • 23
  • 39
  • 6
    I like this answer, because while the documentation describes truth, the software defines truth. `.git/HEAD` is what the software considers to be HEAD. – Don Branson Sep 05 '19 at 15:47
  • 17
    For its conceptual definition alone, this should be the accepted answer. – ata Apr 06 '20 at 14:23
  • 8
    I really think this is the best answer. The others imply that `HEAD` is the tip of a branch, but it is not, it is like a tape head. A really easy way to see this in action is `git checkout HEAD~1` to go back one commit, then `git checkout HEAD~1` to go back another commit. If `HEAD` always referred to the most recent commit on a branch the second command would be the same as the first - it is not. The second command moves your `HEAD` back one more time, i.e. you are now two commits from the tip of the branch. It's subtle but important. – Dave Kerr Jun 14 '21 at 14:05
  • 6
    I liked your expression "HEAD is YOU". – Ivan dal Bosco Apr 21 '22 at 08:48
  • 4
    This answer should be accepted, it's well explained! – Ahmad Nov 22 '22 at 06:07
81

HEAD is just a special pointer that points to the local branch you’re currently on.

From the Pro Git book, chapter 3.1 Git Branching - Branches in a Nutshell, in the section Creating a New Branch:

What happens if you create a new branch? Well, doing so creates a new pointer for you to move around. Let’s say you create a new branch called testing. You do this with the git branch command:

$ git branch testing 

This creates a new pointer at the same commit you’re currently on

enter image description here

How does Git know what branch you’re currently on? It keeps a special pointer called HEAD. Note that this is a lot different than the concept of HEAD in other VCSs you may be used to, such as Subversion or CVS. In Git, this is a pointer to the local branch you’re currently on. In this case, you’re still on master. The git branch command only created a new branch — it didn’t switch to that branch.

enter image description here

DavidRR
  • 18,291
  • 25
  • 109
  • 191
Alexandr
  • 5,460
  • 4
  • 40
  • 70
  • 6
    Nice, could use a picture showing the detached HEAD case though – Don Hatch Jul 10 '15 at 02:49
  • @DonHatch, Good explanation of detached HEAD http://stackoverflow.com/a/35301963/1074179 – Alexandr Jul 03 '16 at 14:50
  • 7
    Nice answer. Branches are nothing but labeled commits, when you make new commits , this label is moved to the new new commit. When you checkout a commit that doesn't have a label , it's in detached HEAD state. That means HEAD is pointing to a commit that doesn't have a branch label. If you checkout `34ac2` in above example, now HEAD would be pointing to that commit and it's called a detached HEAD. In this state, you can make changes, experiment, and commit changes too, but once you checkout a different branch, you'd lose all your changes, unless of course you create a new branch. – Rukshan Sep 09 '18 at 11:04
  • 3
    @sleepwalkerfx but you can checkout a commit that has a branch label and still be in detached head state because your HEAD is no longer pointing to the branch label but the branch's commit id – Marc Mar 18 '20 at 20:16
  • @Marc when you checkout a commit that has a branch label (in other words a branch), HEAD moves with you. It won't be pointing to somewhere else. So, in this case, you won't be in the detached state. – Rukshan Mar 22 '20 at 18:24
  • 2
    @sleepwalkerfx I think we're talking about semantics at this point. You are correct a branch label is a text reference to a particular commit. It is, however, not a commit. So if you did a `git log` and got something like `commit ad0265... HEAD -> foo ...` that would mean the `foo` branch is a reference to commit id `ad0265`. Doing a checkout of the text reference `foo` is not a detached head. Doing a checkout of the commit id `ad0265` would result in a detached head. May be I'm missing some subtlety of what you're communicating. I hope this wall of text helps discover where I'm lost. – Marc Mar 24 '20 at 15:53
  • @Marc I think now I get what you meant. What you said is true. And when you checkout a single commit (whether or not it has a branch label) you're no longer in a branch. Because of this, your branch label doesn't move forward with your next commits. That's why it's still in detached state. – Rukshan Mar 30 '20 at 09:33
  • @RukshanMarapana "but once you checkout a different branch, you'd lose all your changes, unless of course you create a new branch" That's not super accurate. If you don't commit it, then it would just be another commit in git. But it won't be labeled with a branch. You can later retrieve that commit through `git reflog`, but it's super difficult, because you have to know the SHA of the commit. – mfaani Feb 03 '21 at 20:30
  • Sorry I meant to say “if you commit it” – mfaani Feb 04 '21 at 23:31
  • @mfaani, you can edit your comments. – Pedro Machado Oct 16 '22 at 17:56
68

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.

Rob Bednark
  • 25,981
  • 23
  • 80
  • 125
jasoares
  • 1,811
  • 17
  • 22
  • 44
    So the true def is "the parent of your next commit" – nicolas Jan 08 '13 at 21:33
  • 1
    and also "the thing pointing at the next branch that will move" – nicolas Jan 08 '13 at 21:35
  • @nicolas - I don't *think* that is true. HEAD can point at any commit, it does not necessarily have to point at a branch - when it does not, you are in "detached HEAD" mode. – scubbo Jun 03 '13 at 14:46
  • It can point to any commit indeed, but that does not define what it is. afaik what was written in jan is its definition – nicolas Jun 03 '13 at 14:57
  • 28
    The video is great, but unfortunately, it makes an ill-suited answer for Stack Overflow. What if the video is taken down sometime in the future? Then your link will point to nothing. A better answer would include a transcript of what Scott says in the video. –  Jul 26 '13 at 02:09
  • 4
    Scott says HEAD is a pointer to a branch. But HEAD can point to old commits too. This is sooo confusing. – Fixee Jun 16 '14 at 15:47
  • Nice to see a reference, but the answer is nowhere to be found in your answer. :P – lindhe May 02 '15 at 21:46
47

Assuming it is not a special case called "detached HEAD", then, as stated in the O'Reilly Git book, 2nd edtion, p.69, HEAD means:

HEAD always refers to the most recent commit on the current branch. When you change branches, HEAD is updated to refer to the new branch’s latest commit.

so

HEAD is the "tip" of the current branch.

Note that we can use HEAD to refer to the most recent commit, and use HEAD~ as the commit before the tip, and HEAD~~ or HEAD~2 as the commit even earlier, and so forth.

nonopolarity
  • 146,324
  • 131
  • 460
  • 740
29

HEAD refers to the current commit that your working copy points to, i.e. the commit you currently have checked-out. From the official Linux Kernel documentation on specifying Git revisions:

HEAD names the commit on which you based the changes in the working tree.

Note, however, that in the upcoming version 1.8.4 of Git, @ can also be used as a shorthand for HEAD, as noted by Git contributor Junio C Hamano in his Git Blame blog:

Instead of typing "HEAD", you can say "@" instead, e.g. "git log @".

Stack Overflow user VonC also found some interesting information on why @ was chosen as a shorthand in his answer to another question.

Also of interest, in some environments it's not necessary to capitalize HEAD, specifically in operating systems that use case-insensitive file systems, specifically Windows and OS X.

Community
  • 1
  • 1
24

Take a look at Creating and playing with branches

HEAD is actually a file whose contents determines where the HEAD variable refers:

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

In this repository, the contents of the HEAD file refers to a second file named refs/heads/master. The file refs/heads/master contains the hash of the most recent commit on the master branch.

The result is HEAD points to the master branch commit from the .git/refs/heads/master file.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
onmyway133
  • 45,645
  • 31
  • 257
  • 263
19

After reading all of the previous answers, I still wanted more clarity. This blog at the official git website http://git-scm.com/blog gave me what I was looking for:

The HEAD: Pointer to last commit snapshot, next parent

The HEAD in Git is the pointer to the current branch reference, which is in turn a pointer to the last commit you made or the last commit that was checked out into your working directory. That also means it will be the parent of the next commit you do. It's generally simplest to think of it as HEAD is the snapshot of your last commit.

user3751385
  • 3,752
  • 2
  • 24
  • 24
  • 3
    *The HEAD: last commit snapshot, next parent* is not accurate. `HEAD` is not a commit; it *points to* one. – jub0bs Sep 26 '14 at 18:07
  • 1
    No need for sarcasm; before your edit, even though the quote was accurate, the big bold letters were a simplification and a bit misleading. Now, it's better. – jub0bs Sep 27 '14 at 15:50
  • 2
    IF you read the next line: The HEAD in Git is the **pointer** to the current branch reference, which is in turn a **pointer** to the last commit you made or the last commit that was checked out into your working directory. -- Please note the use of the word "pointer" there. – user3751385 Sep 27 '14 at 15:51
  • 2
    While the "last commit snapshot" description does give a conceptual feel for how HEAD is typically supposed to be used, it's really not accurate. If I make a commit, then switch to another branch, HEAD doesn't point to the last commit snapshot anymore. It points to the last commit snapshot on the branch I just switched to. If I `checkout HEAD^`, now HEAD doesn't even point to the last commit snapshot on any branch. – LarsH Mar 01 '19 at 02:36
  • 2
    "The parent of your next commit (if you were to commit right now)" is more accurate, but there are many other operations in git besides commit that are affected by HEAD. Really, in the end, HEAD is HEAD, and its nature is defined by how it affects commands like `commit`, `merge`, `rebase`, `log`, etc. But conceptually maybe "(pointer to) the current position" is a good summary. – LarsH Mar 01 '19 at 02:39
18

What is HEAD in Git? (conceptually)

HEAD is a pointer to the currently checked out branch or commit, it answers the question: Where am I right now in the repository? Or, in other words, it's Git's way of knowing on which commit to mirror your local Working Tree on, and whether you're currently working on a branch (attached) or not (detached).

Detached HEAD

HEAD can be in either of two states, attached or detached, depending on if you've checked out a branch or not. Default state is attached, where any manipulation to the history is automatically recorded to the branch HEAD is currently referencing.

In detached state experimental changes can be made without impacting any existing branch. See infographic below illustrating the difference between committing in attached vs detached state.

Illustration of HEAD in attached and detached state.

A common misconception is that the message You are in 'detached HEAD' state is of erroneous tone, when in fact it just describes how HEAD is referencing the current snapshot.

Operations than can leave HEAD in detached state:

  • Checking out a particular commit, i.e.
    $ git checkout 14ko3
    
  • Explicitly checking out a remote branch, i.e.
    $ git checkout origin/master
    
  • Switching to a branch using the detached flag, i.e.
    $ git switch master --detached
    
  • Checking out a tag, i.e.
    $ git checkout v1.0.1
    
  • Performing an interactive rebase, or a regular rebase containing conflicting changes

Moving from detached to attached state

To move from detached to attached state, you can either create a new branch from where you're at, or switch back to an existing branch.

Note: any commits created in detached state will eventually (post garbage collection) be discarded if you switch to another existing branch, without first persisting your changes in a new branch.

Inspecting the state of HEAD

Figuring out which state HEAD is currently in can be done in different ways, here are two options.

  • Using show
    $ git show HEAD --oneline
    14ko3 (HEAD, master) C1
    
    # If attached, the output would have been
    14ko3 (HEAD -> master) C1
    
  • Using status
    $ git status
    HEAD detached at 14ko3
    

What is HEAD exactly? (technically)

If you ever want to explicitly see what HEAD is referencing you can always inspect the .git/HEAD file, which is the actual file Git uses internally to manage HEAD. The file contains the name of the branch or commit hash depending on if HEAD is detached or not.

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

# If detached, the output would have been
14ko36e295f1a98ec57397b3acc7bc247da61ff5

Source: Above excerpt is taken from this full length post on the subject: What is HEAD in Git?

15

I'd just like to detail a few things in Greg Hewgil's accepted answer. According to the Git Pocket Guide

Branch:

the branch itself is defined as all points reachable in the commit graph from the named commit (the “tip” of the branch).

HEAD: A special type of Ref

The special ref HEAD determines what branch you are on...

Refs

Git defines two kinds of references, or named pointers, which it calls “refs”:

  • A simple ref, which points directly to an object ID (usually a commit or tag)
  • A symbolic ref (or symref), which points to another ref (either simple or symbolic)

As Greg mentioned, HEAD can be in a "detached state". So HEAD can be either a simple ref (for a detached HEAD) or a symref.

if HEAD is a symbolic ref for an existing branch, then you are “on” that branch. If, on the other hand, HEAD is a simple ref directly naming a commit by its SHA-1 ID, then you are not “on” any branch, but rather in “detached HEAD” mode, which happens when you check out some earlier commit to examine.

mike
  • 1,135
  • 4
  • 22
  • 39
  • 1
    Thank you, @mike! This is the first answer that clarifies what happens when you check out an earlier commit. Looking at the [book](https://git-scm.com/book/en/v2) on the git website, I got the impression that a "detached HEAD" was a pathological state you only got into if you did some weird rebasing thing. But checking out an earlier commit is not a strange thing to do, and when you do that, HEAD is not "the tip of the current branch." So this is the first time I feel like I actually understand. – Nat Kuhn May 12 '19 at 21:20
7

I think 'HEAD' is current check out commit. In other words 'HEAD' points to the commit that is currently checked out.

If you have just cloned and not checked out I don't know what it points to, probably some invalid location.

Nataraj
  • 79
  • 1
  • 1
  • Yes, the special reference `HEAD` is whatever commit you've currently got checked-out. See [the manual](http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is) for details (relevant paragraph immediately follows Fig 3.4). – Calrion Oct 31 '12 at 03:51
  • 1
    If you clone a repository, git will by default check out the `master` branch - so HEAD will point to master. – sleske Aug 16 '13 at 14:14
  • 1
    @sleske if you clone a repository with no special options git will check out the remote head. it is usually `master`, but it is not always. See `remote set-head` – De Novo Mar 01 '19 at 13:58
  • My previous comment was correct except for the reference to `remote set-head`, which only impacts the local default branch, and won't change the default at the server. – De Novo Mar 05 '19 at 02:05
6

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.

tjb
  • 11,480
  • 9
  • 70
  • 91
5

Head points to the tip of the currently checked out branch.

enter image description here

In your repository, there is a .git folder. Open the file in this location: .git\refs\heads. The (sha-1 hash) code in that file (master in most cases) will be the most recent commit, i.e the one seen in the output of the command git log. More info on the .git folder: http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html

stack1
  • 1,004
  • 2
  • 13
  • 28
  • 3
    It's a common misconception that the tip of the current branch points to the most recent commit. Typically that's true, but it's also not uncommon to `git reset HEAD^`, and then the most recent commit (the former tip) is no longer pointed to by the tip of the branch. – LarsH Mar 01 '19 at 02:45
4

It feels like that HEAD is just a tag for the last commit that you checked out.

This can be the tip of a specific branch (such as "master") or some in-between commit of a branch ("detached head")

Vertexwahn
  • 7,709
  • 6
  • 64
  • 90
3

HEAD is nearly literally the head of the branch. So when you are observing a branch, you are looking at the latest commit, which is this same head of the branch. However, you can point yourself to be looking at another commit further back in the history of this branch, and when you do that, you are moving the HEAD to a previous commit. As the HEAD belonged naturally to the latest commit in the branch, it is considered detached.

A visual representation. Each branch is a caterpillar, and each commit is a segment of the creature. So the HEAD will be in the segment that is most ahead. If you remove the HEAD from that to another segment to be used, you have detached the head from the natural segment. Hope it makes any sense.

Now if you detach the HEAD in the main branch, then checkout newFeature, and checkout main again, the HEAD will still be detached, and on top of another commit. I see the HEAD as a looking glass that you can point at where you want.

Goma
  • 79
  • 6
2

In addition to all definitions, the thing that stuck in my mind was, when you make a commit, GIT creates a commit object within the repository. Commit objects should have a parent ( or multiple parents if it is a merge commit). Now, how does git know the parent of the current commit? So HEAD is a pointer to the (reference of the) last commit which will become the parent of the current commit.

Anwar Husain
  • 1,414
  • 14
  • 19
2

Git is all about commits.
And Head points to the commit which you currently checked out.

$ git cat-file -t HEAD
commit

Whenever you checkout a branch, the HEAD points to the latest commit on that branch. Contents of HEAD can checked as below (for master branch):

$ cat .git/refs/heads/master
  b089141cc8a7d89d606b2f7c15bfdc48640a8e25
S R Chaitanya
  • 738
  • 7
  • 11
2

There can be multiple heads in a repository. And total number of heads is always equals to total number of branches present in the repository,which means heads are nothing but latest commits of each branch

But there will be only one HEAD for a repository.HEAD is a reference which references the latest commit done at the current branch.

Its like eye of git user.Whichever commit the HEAD is referencing to, the repository starts reflecting the condition the repository had during that particular commit.

The basic nature of HEAD is to always refer the latest commit of current branch but we can move HEAD to any commit of the current branch by using git checkout "commit-hash"

Note: We can easily get commit-hash by using command git log --oneline

2

To understand what HEAD is, let use a practical example with two different branches, main and feature1 from two different developers Dev1 and Dev2 working on the same project.

Case 1 with Dev1's main branch:

name~/repo (main)
$ ls -al
total 9
drwxr-xr-x 1 AlphaLy 197121  0 Dec 22 15:09 ./
drwxr-xr-x 1 AlphaLy 197121  0 Dec 21 20:35 ../
drwxr-xr-x 1 AlphaLy 197121  0 Dec 22 15:09 .git/
-rw-r--r-- 1 AlphaLy 197121 20 Dec 21 20:35 README.md
-rw-r--r-- 1 AlphaLy 197121  0 Dec 22 15:09 test.txt

Next1

name~/repo (main) 
$ cd .git/
name~/repo/.git (GIT_DIR!)
$ ls
COMMIT_EDITMSG  description  HEAD    index  logs/     ORIG_HEAD    refs/
config          FETCH_HEAD   hooks/  info/  objects/  packed-refs

Next2

name~/repo/.git (GIT_DIR!)
$ cat HEAD
ref: refs/heads/main

We can clearly see that HEAD is a file with a line pointing to a file called main located inside the refs/heads directory (heads is a directory inside the refs directory). Refer to Next1 step to locate the refs directory

Now lets go to the Next1 step and cd into the refs directory and search for the main file inside the heads directory and see what it contains

name~/repo/.git (GIT_DIR!)
    $ cd refs
    
name~/repo/.git/refs (GIT_DIR!)
    $ ls
    heads/  remotes/  tags/
    
name~/repo/.git/refs/ (GIT_DIR!)
    $ cd heads/
    
name~/repo/.git/refs/heads (GIT_DIR!)
    $ ls
    main  maxi

name~/repo/.git/refs/heads (GIT_DIR!)
$ cat main
8b25d89f3396177416c055ab07ebf778616eecdd

8b25d89f3396177416c055ab07ebf778616eecdd is the current commit. So, we can say that HEAD refers to a file named main (always named after the current branch) that contains the current commit (the 40 digit character above). So HEAD refers to the current commit.

Case 2 with Dev2's feature1 branch

Here, the only difference will be in the Next2 step

name~/repo/.git (GIT_DIR!)
$ cat HEAD
ref: refs/heads/feature1

and the following:

    name~/repo/.git (GIT_DIR!)
   $ cat feature1
03fbf973ac1014085864234010b82393208ebbd6

03fbf973ac1014085864234010b82393208ebbd6 is the current commit on the feature1 branch. So, here again HEAD refers to a file called feature1 (named after the current branch) that contains the current commit (the 40 digit character above).

Conclusion:

HEAD is refers to the current commit not the current branch. It's just a coincidence that the file that contains that current commit is named after the current branch that we tend to say that 'HEAD refers to the current branch'.

ITselect
  • 133
  • 1
  • 1
  • 10
1

I am also still figuring out the internals of git, and have figured out this so far:

Let's say the current branch is master.

  1. HEAD is a file in your .git/ directory that normally looks something like this:
% cat .git/HEAD
ref: refs/heads/master
  1. refs/heads/master is itself a file that normally has the hash value of the latest commit of master:
% cat .git/refs/heads/master 
f342e66eb1158247a98d74152a1b91543ece31b4
  1. If you do a git log, you will see that this is the latest commit for master:
% git log --oneline 
f342e66 (HEAD -> master,...) latest commit
fa99692 parent of latest commit

So my thinking is the HEAD file is a convenient way to track the latest commit, instead of remembering long hash values.

Jerry Chen
  • 321
  • 3
  • 4
0

Take a look at http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is

Figure 3-5. HEAD file pointing to the branch you’re on.

Ting Wang
  • 19
  • 2
  • 4
    Link only answers are generally frowned upon on Stackoverflow, please inline the relevant information in your answer. – HaskellElephant Oct 11 '12 at 08:07
  • 2
    This isn't entirely correct. What `HEAD` refers to depends on whether you're talking about a bare vs a non-bare repo. In the context of a non-bare repo, it effectively refers to the currently checked-out commit, which doesn't require there to be a branch attached to it (i.e. when in detached `HEAD` state). –  Aug 07 '14 at 20:29
0

These two may confusing you:

head

Pointing to named references a branch recently submitted. Unless you use the package reference , heads typically stored in $ GIT_DIR/refs/heads/.

HEAD

Current branch, or your working tree is usually generated from the tree HEAD is pointing to. HEAD must point to a head, except you are using a detached HEAD.

Marcus Thornton
  • 5,955
  • 7
  • 48
  • 50
0

A branch is actually a pointer that holds a commit ID such as 17a5. HEAD is a pointer to a branch the user is currently working on.

HEAD has a reference filw which looks like this:

ref:

You can check these files by accessing .git/HEAD .git/refs that are in the repository you are working in.

Okd
  • 55
  • 5
0

HEAD actually is just a file for storing current branch info

and if you use HEAD in your git commands you are pointing to your current branch

you can see the data of this file by cat .git/HEAD

Mahdi mehrabi
  • 1,486
  • 2
  • 18
  • 21
0

I haven't figured it out myself yet, but Silfheed's link to the "post-it notes slapped on a node" definition is the best I've found so far.

I would like to share my impressions of the search for a definition, otherwise why should I keep it to myself. I understand it really as stickers glued to the current position in the space of the Git tree. I miss just such a term - the current position in the GIT tree, which has its own attributes that indicate where we are.

Such concepts as "reference" or "pointer" are not clear to me. It seems to me that they imply a new level of abstraction, from the inside of which we "refer" to something. This may not be true, but this is how I see it so far.

Oleg
  • 17
  • 3
  • 1
    This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://stackoverflow.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://stackoverflow.com/help/whats-reputation), you can also [add a bounty](https://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/late-answers/33463092) – user12256545 Dec 22 '22 at 12:09
-5

As a concept, the head is the latest revision in a branch. If you have more than one head per named branch you probably created it when doing local commits without merging, effectively creating an unnamed branch.

To have a "clean" repository, you should have one head per named branch and always merge to a named branch after you worked locally.

This is also true for Mercurial.

dukeofgaming
  • 3,108
  • 4
  • 28
  • 35