0

In the Git glossary documentation (here):

  1. HEAD is defined to be "The current branch". Later in the same paragraph, it went further by saying "HEAD is a reference to one of the heads in your repository".

  2. However, the paragraph above it defines what a head is: "a named reference to the commit at the tip of a branch."

This answer on StackOverflow cited, "as stated in the O'Reilly Git book, 2nd edtion, p.69, HEAD always refers to the most recent commit on the current branch", which means "HEAD is the tip of the current branch".

I'm confused. Is the all-capital-letter HEAD (1) the current branch, or (2) the tip of the current branch?

NOTE: this question didn't resolve my question.

Leedehai
  • 3,660
  • 3
  • 21
  • 44
  • 1
    `HEAD` can also include detached `HEAD` which means there is no branch, it is only pointing at a commit. Are you including this in your required definition? – Fantastic Mr Fox Sep 26 '18 at 16:44
  • 3
    This is a question about linguistics. Technically, HEAD is a single commit (the tip of the branch). But, the branch is also just a reference to the tip of the branch, so HEAD is the branch. We humans think of the branch as the commit and all its ancestors, but really a branch is just a ref to a single commit. – William Pursell Sep 26 '18 at 16:46
  • Related (with diagrams): https://stackoverflow.com/questions/26049827/how-are-the-terms-head-head-and-tip-different/26049871#26049871 – jub0bs Sep 26 '18 at 16:53
  • @FantasticMrFox Oh sorry didn't think of that. Maybe I should include this one. – Leedehai Sep 26 '18 at 17:02
  • Also related: https://stackoverflow.com/questions/25068543/what-exactly-do-we-mean-by-branch – jub0bs Sep 26 '18 at 17:18

3 Answers3

3

Both. We're talking about:

  • A branch, with its intuitive meaning from a human point of view: a chain of commits which sprouts from either the "trunk" (typically master) or the ground (the initial commit);

  • A branch, as seen by Git, which keeps track of the most recent commit only. To Git, a branch is only a named pointer that refers to the tip of a commit chain.

Once you know that both definitions coïncide in practice, there's no actual ambiguïty.

Quentin
  • 62,093
  • 7
  • 131
  • 191
  • I'd eschew the term "tag" for describing a branch: too much room for confusion. Also, you may be interested in https://stackoverflow.com/questions/25068543/what-exactly-do-we-mean-by-branch – jub0bs Sep 26 '18 at 16:54
  • @jubobs I wouldn't: branches behave like tags, and then some, and tags are pretty self-explanatory. – Quentin Sep 26 '18 at 17:06
  • But the same Git Glossary documentation also said "A 'branch' is an active line of development. The most recent commit on a branch is referred to as the tip of that branch." So it looks the documentation adopts the human intuitive definition to define what a "branch" is, but laster uses Git's definition to define what a "HEAD" is. – Leedehai Sep 26 '18 at 17:06
  • 1
    @Leedehai exactly. Whether it's about the whole chain or just the tip can generally be deduced from context. – Quentin Sep 26 '18 at 17:07
  • @Quentin That's just confusing... Even though branches and tags have similarities, their semantics are very different. – jub0bs Sep 26 '18 at 17:17
  • @jubobs I'm open to alternatives if you have a better way to describe that. – Quentin Sep 26 '18 at 17:22
  • @Quentin Well, I'd use a more neutral term, such as "pointer". – jub0bs Sep 26 '18 at 17:23
  • @jubobs yeah, that fits. Thanks! – Quentin Sep 26 '18 at 17:24
  • 1
    "Both" is the right answer (and I've upvoted). The other trick to know is that internally, Git has two interfaces for getting an answer about `HEAD`: one answers *which **branch name** is `HEAD` attached-to?* and the other answers *which **commit** does `HEAD` select?* (These break down into even more internal interfaces, but those are the place to start: Do we want the *symbolic name*, e.g., is `HEAD` `master` right now? Or do we want the *commit hash*, e.g., is `HEAD` commit `a123456...` right now?) – torek Sep 26 '18 at 18:34
  • _"...most recent commit only"_ => A branch (actually a branch head, according to the Git glossary) can point to a commit that is _not_ the most recent, no? E.g. we can do `git reset HEAD~`. – starriet May 04 '23 at 01:44
  • 1
    @starriet it's kind of tautological, but after you've done that the child commit you left behind is out of the equation, so the target commit becomes the most recent one. – Quentin May 04 '23 at 09:57
3

Independently of what the documentation says (which might have to get some correction, dunno), HEAD is always where you are standing, which might very well be the tip of a branch... but it might not. Say, you checkout master~2 and there's no branch pointing to master~2. Then HEAD is on master~2, and you are working on detached HEAD state.

eftshift0
  • 26,375
  • 3
  • 36
  • 60
3

HEAD is simply where you're currently pointing. This can be either a branch (which is a pointer to a stack of commits) or a commit itself. In the typical usecase, it's going to point to a branch. However, it can also point to a commit (this snippet assumes you're at the root of some git repo):

(base) Matthews-MacBook-Pro:abc matt$ git checkout -b test
Switched to a new branch 'test'
(base) Matthews-MacBook-Pro:abc matt$ cat .git/HEAD
ref: refs/heads/test
(base) Matthews-MacBook-Pro:abc matt$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
(base) Matthews-MacBook-Pro:abc matt$ cat .git/HEAD
ref: refs/heads/master
(base) Matthews-MacBook-Pro:abc matt$ git log -2
commit 5d4fe79e315c302722cfdfef3dd049f720db5acc (HEAD -> master, origin/master, origin/HEAD, test)
Author: Matt Messersmith <nah@blah.com>
Date:   Tue Sep 25 20:05:38 2018 -0400

    Problem 155 sol.

commit 73cdc8f6a679664e3b92a826377b280aadf31de1
Author: Matt Messersmith <nah@blah.com>
Date:   Tue Sep 25 19:47:50 2018 -0400

    An easy warmup.
(base) Matthews-MacBook-Pro:abc matt$ git checkout 73cdc8f6a679664e3b92a826377b280aadf31de1
Note: checking out '73cdc8f6a679664e3b92a826377b280aadf31de1'.

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 73cdc8f An easy warmup.
(base) Matthews-MacBook-Pro:leetcode matt$ cat .git/HEAD
73cdc8f6a679664e3b92a826377b280aadf31de1

The difference between a "branch" and "tip of a branch" doesn't really make much sense. It's sort of like asking the difference between a pointer and the tip of the pointer. Branches just point to things (stacks of commits), and HEAD acts in a similar fashion (can point to a branch or a commit). I suppose it comes down to semantics and linguistics.

HTH!

Matt Messersmith
  • 12,939
  • 6
  • 51
  • 52