Conversation

poll: how confident do you feel that you know what HEAD means in git?

11% 100%
35% pretty confident
39% somewhat confident?
14% literally no idea
0
0
0

@b0rk I’d suggest another option: “I have a vague idea that more or less works but given all the other things I’ve learned about git I’m terribly confidant that it’s wrong in some fundamental way”

2
0
0
I think it means...
Show content

@b0rk

...last commit on the current branch

But I suspect that this is often true but not actually what it means in every context 🤔

Edit: and I was wrong lol

Meaning I don't understand "git reset" either

1
0
0
I think it means...
Show content

@davey_cakes yep, I think it's pretty common to think that's what HEAD is (and that definition often works fine in practice!), but it's technically not correct. i talked about what it is here: https://wizardzines.com/comics/the-current-branch-head/

0
0
0

ok here's a different question: what do you think HEAD means in git? mostly interested in answers from folks who are not totally confident in their answer

(please no arguing or telling other people they're wrong, I'm just curious about people's different impressions, if people are "wrong" in some way, IMO that's git's fault for being confusing and I want to know about it)

2
0
0

@b0rk I like the name HEAD. To me the word suggests the most up-to-date work

How do I put my current branch into my bash prompt?

2
0
0

@chris_e_simpson not on my laptop, so can't give you a direct example (feel free to pester me later!), but these pointers should help:

* https://tldp.org/HOWTO/Bash-Prompt-HOWTO/x264.html
* "rc" files (e.g. `~/.bashrc` if you use bash) are executed at the beginning of every terminal session to set env variables

1
0
0

@chris_e_simpson (also, hello fellow snowboarder! Hope you're having a good season. I'm not on my laptop *because* I'm on my way to the snow 😁)

0
0
0

@chris_e_simpson depends on your shell and how fancy of a prompt you want, did a sort of survey a while back and there are some approximate stats on what people prefer here https://mastodon.social/@gnomon/112022873756636860#.

1
0
0

@chris_e_simpson personally if I were using bash or zsh I'd probably start with this https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh (it's built into git)

0
0
0

@jacob @b0rk git is like a leaky abstraction generator. you can build a mental model of how it works to some degree of accuracy that mostly works most of the time but it bites you all the time.

0
2
0

all of these replies about what HEAD means in git are amazing and are all extremely reasonable things to conclude based on git's behaviour and they really make me think HEAD is a pretty misleading name

4
0
0

@b0rk

It made sense in SVN, but I really think git should have picked something else.

1
0
0

@mwl yeah I think so. that ship has sailed though I guess.

0
0
0

another poll: how do you think of HEAD in git?

0% a pointer to the current commit
0% a pointer to the current branch (usually)
0% other
8
0
0

@b0rk I think it's... the commit that's currently checked out?

To get to that answer I had to reason through what must be true to make "git checkout HEAD^" and similar commands do what they do

0
0
0

@b0rk It's definitely a pointer.. Not sure I agree with the wording you've chosen to use tho. I'd say it's a pointer *in* the current branch (usually)..

So I chose other. :)

1
0
0

@XenoPhage what do you mean by "in the current branch”? (also I'd be curious about how that relates to the contents of the file `.git/HEAD`, if it does)

1
0
0

@b0rk I know it's kind-of-wrong but I voted for the second one and I hope my peers won't judge me too harshly. 😢

1
0
0

@Palleas the second one ("the current branch”) is definitely the "correct" answer, i'm curious about why you think it's wrong!

0
0
0

@b0rk I don't think either of the options are accurate, although "a pointer to the current commit" is slightly closer to the truth than "pointer ot the current branch".

a clear counterexample is that if you just ran git init, there are no commits, so HEAD can't possibly point to a commit.

I think a better description is that it's a pointer to your current *position* in the commit tree. after git init, it points to the primary branch, e.g. "main". if you do a local commit, HEAD points there.

1
0
0

@gsuberland I'm confused about what you're saying -- are you saying that HEAD is different before and after you make your initial commit in a repo?

that's definitely not what I see in `.git/HEAD`:

2
0
0

@b0rk My understanding is that HEAD points at the latest commit in the branch you're currently in. So if you're in main, it's the latest commit there. If you're in dev, it's the latest commit in that branch. The “usually" bit is if you're in a detached state, ie, not in a branch but pointing at a specific commit instead, that HEAD points at that commit.

But if you're in a branch and not on the latest commit, HEAD still points at the latest commit.

I don’t tend to think about things in relation to HEAD, though, so I could be wrong here.

1
0
0

@XenoPhage thanks! appreciate hearing how folks are thinking about this

0
0
0

@b0rk a file in .git that points to either a commit or a ref; git uses this as the "current" commit for things like git status

(I'd say I'm somewhere between "pretty confident" and "100%", but second-guessing because the question's being asked)

2
0
0

@Gaelan the only thing I would say is that I think it would be VERY weird for HEAD to contain a ref that's not a branch (you can edit .git/HEAD manually to point it to a tag or remote-tracking branch or whatever, but I'm not aware of any other way to make HEAD be a non-branch ref other than manually editing the file, I'm very curious if that's possible though!)

1
0
0

@Gaelan (not meant as a correction or anything, I've just been thinking about if there's ever any situation where HEAD is something OTHER than a branch or a commit and I haven't been able to come up with one yet)

0
0
0

@b0rk ("to either a commit or a ref" isn't something I'd really thought about before, but given that detached HEAD is a thing, but normally HEAD stays pointing to the latest commit even after you make a new commit, I guess it must be able to be either)

0
0
0

@b0rk answered number 1 even though I know that answer 2 is "more correct", because truthfully 1 is how I think of it more-often in daily usage.

(Though, depending on your definition of "pointer", arguably 1 is also fully correct? Just that usually the "pointing" is via indirection - is "a pointer to (the current branch, which is itself) a pointer to the current commit" itself "a pointer to the current commit"? Computers would say no, but what do they know!?)

1
0
0

@Amikke @Palleas yeah the situation is a bit hard to summarize in 7 words (HEAD can also be a pointer to a commit but usually it isn’t)

1
0
0

@b0rk It depends on what kind of thing it names. For `git commit`, it's a branch; for `git show` it's a commit; for `git grep` it's a snapshot/tree.
So, a pointer to the current (branch->commit->tree), depending on how far along the pointer path one goes.

1
0
0

@encukou thanks, that’s a nice way of thinking about it

0
0
0

@b0rk I dont understand the second option because to me a branch is a string of commits. If HEAD were just pointer to a branch, you could seemingly replace it with the branch name. As far as I am aware this is never done.

I can kind if see it working if the branch name is a actually a reference to the value of HEAD for a given branch? But that is certainly not how I think about it.

2
0
0

@b0rk lol now that i looked through the responses.

0
0
0

@b0rk in this case HEAD is pointing to the head of the main branch, which points after the last commit in that branch, so the label you see stays the same.

1
0
0

@b0rk you've got HEAD, which is your local working pointer, which points to some arbitrary location in the commit graph.

then you've got branch metadata which specifies that branch's extents (branch start and branch head) in the commit graph.

so what you're seeing here is essentially a symlink. rather than HEAD pointing after some specific commit, it's symlinked to the main branch's head pointer, which itself points to an actual location in the commit tree.

1
0
0

@b0rk and if you think about it, this makes sense from a usability perspective. if HEAD was always a *direct* pointer to a position in the commit tree, e.g. via commit hash, every time you synced from remote and fetched new commits you'd end up with your HEAD still pointing at wherever you last committed or synced, rather than after the last commit in the currently checked out branch. by having HEAD symlink to refs/heads/main (i.e. head of the main branch) it keeps you in the ideal position.

2
0
0

@b0rk so most of the time HEAD ends up symlinked to refs/heads/<branch>, which itself points to a position in the commit graph.

it's possible for HEAD to not point at the head of a branch, and AIUI that's what "detached HEAD" means - you've got HEAD directly pointing to a location in the commit graph rather than symlinked to a branch head.

1
0
0

@gsuberland why do you say that HEAD isn’t a pointer to a branch if it’s a symlink to refs/heads/main?

0
0
0

@b0rk so perhaps this is a better way to look at it

1
0
0

@b0rk I think the key distinction is that HEAD (when attached) doesn't point to a branch, but to a branch head, which itself is a pointer to the location where the next commit will be placed on that branch.

1
0
0

@gsuberland thanks, appreciate it! i need to remember that not everyone thinks of a branch and a branch head as being totally interchangeable concepts (i do because branches are stored in git as their head but that doesn’t make them the same )

0
0
0

@b0rk @gsuberland I think we need to acknowledge that the refspec HEAD and .git/HEAD are not always the same. In the case of no branches or commits existing, .git/HEAD is there, but HEAD the refspec does not exist:

1
0
0

@b0rk

A pointer to the *latest* commit (not necessarily "current" commit) in whatever I'm working on.

1
0
0

@bignose thanks! what’s the difference between the latest and current commit?

1
0
0

@b0rk

In my mind, "the current commit" is whatever I'm currently working on. This might differ from "latest" if, for example, I'm in the middle of a rebase or bisect.

And "the latest commit" is whatever is conceptually "at the end" of the branch's timeline.

But now, writing this out, I am less sure about the concept. And I don't know which one HEAD maps to :-/

1
0
0

@b0rk Do we get the answer too?

1
0
0

@alper i wrote about it here but honestly all these replies made me want to really rethink how I'm explaining it

- https://wizardzines.com/comics/the-current-branch-head/
- https://wizardzines.com/comics/detached-head-state/

0
0
0

all of these answers about what HEAD is are SO helpful and have really made me rethink how I'm explaining it in the zine

1
0
0

@b0rk I'm sure you're too wily to take this on, but I'd bet you are very well placed to write a version control system that isn't user hostile.

2
0
0

@williampietri it's still pretty early but I think what the jj developers are doing is interesting https://github.com/martinvonz/jj

0
0
0