doc: checkout: rewrite detached HEAD state explanation
Subsystems (2)
PATCH 1/1 doc: checkout: rewrite detached HEAD state explanation
From: Julia Evans <[email protected]>
The current explanation has the following issues:
- Says detached HEAD state is useful but doesn't explain why
- Takes many paragraphs before explaining what detached HEAD state is
- It's common for users to accidentally end up in detached HEAD state, but it doesn't explain why that might happen
- One of the UI improvements in git switch is to make it harder to detach accidentally, but that isn't advertised.
See 7968bef06b (switch: only allow explicit detached HEAD, 2019-03-29)
- Too many confusing diagrams
Write a new explanation addressing these issues, and put it in a standalone guide so that we can easily reference it from advice ("see git help detachedhead").
The result is a shorter guide that covers more material.
The framing that "Git considers commits that aren't on a branch/other reference to be garbage" is taken from Steve Klabnik's tutorial
https://steveklabnik.github.io/jujutsu-tutorial/branching-merging-and-conflicts/anonymous-branches.html.
It's funny and it's consistent with the way Git uses the term "garbage collection".
---
doc: checkout: rewrite detached HEAD state explanation
Often when rewriting these explanations I go through a process where I ask users' feedback on the old explanation. Here I didn't do that basically because that process takes a long time and I'm working on a bunch of other time consuming docs projects so I did a quick rewrite based on my previous experience explaining detached HEAD state to folks.
I thought this could be a nice quick docs win on a topic which many users find quite confusing. If the changes here are too controversial I can drop it for now.
Also if folks object to making a separate git help detachedhead guide I'm happy to drop that too. Personally I'm excited about the idea of being able to reference the guides in our advice (which is one of our best tools for getting users info about how to use Git!), but it's not possible to let users jump to a subsection, so this is sort of a hack around that.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2250%2Fjvns%2Fdetached-head-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2250/jvns/detached-head-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/2250
Documentation/detached-head.adoc | 43 ++++++++++ Documentation/git-checkout.adoc | 129 +---------------------------- Documentation/gitdetachedhead.adoc | 14 ++++ advice.c | 1 + command-list.txt | 1 + 5 files changed, 60 insertions(+), 128 deletions(-) create mode 100644 Documentation/detached-head.adoc create mode 100644 Documentation/gitdetachedhead.adoc
Documentation/detached-head.adoc new file +43 -0
@@ -0,0 +1,43 @@ +`HEAD` is where Git stores your current branch. `HEAD` can either be: + +1. A branch, which is your current branch. +2. A commit ID, when you don't have a current branch. + This is called "detached HEAD state". + +It can sometimes be useful for `HEAD` to be a commit ID. +For example, it lets you look at an old version of your code +(with `git checkout COMMIT_ID`). + +The only problem is that if you create new commits while in detached +HEAD state, those commits won't be on a branch. This makes those new +commits much harder to find later. Also, Git considers commits that +aren't on any branch (or a tag or other reference) to be garbage. +Git will eventually permanently delete those "garbage" commits during +garbage collection. + +There are 3 main ways you can end up in detached HEAD state +unintentionally: + +1. `git checkout COMMIT_ID`, where `COMMIT_ID` is a commit ID +2. `git checkout v1.3`, where v1.3 is a tag name +3. `git checkout origin/main`, where `origin/main` is + a remote-tracking branch + +Checking out a tag puts you in detached HEAD state because `HEAD` can +only be a branch or a commit, not a tag or any other reference. +So `git checkout TAG` will set HEAD to the commit for that tag. + +The easiest way to avoid accidentally ending up in detached HEAD state +is to use linkgit:git-switch[1] instead of linkgit:git-checkout[1] to +switch branches. `git switch` won't let you detach unless you explicitly +pass the `--detach` argument. + +To get back onto a branch, you can: + +1. Switch to the branch you want to be on, with `git switch BRANCHNAME`. +2. Create a new branch at the current commit, with `git switch -c BRANCHNAME`. + You might want to do this if you've created new commits, so that you can + find the commit later and so that it won't be garbage collected. + +If you create commits in detached HEAD state that aren't on a branch, +you can find them later using linkgit:git-reflog[1].
Documentation/git-checkout.adoc +1 -128
136 lines not on this page · raw message
Documentation/gitdetachedhead.adoc new file +14 -0
@@ -0,0 +1,14 @@ +gitdetachedhead(7) +=============== + +NAME +---- +gitdetachedhead - How detached HEAD state works + +DESCRIPTION +----------- +include::detached-head.adoc[] + +GIT +--- +Part of the linkgit:git[1] suite
advice.c +1 -0
@@ -291,6 +291,7 @@ void detach_advice(const char *new_name)"\n" " git switch -\n" "\n" +"Run `git help detachedhead` to learn more.\n" "Turn off this advice by setting config variable advice.detachedHead to false\n\n");fprintf (stderr, fmt, new_name);
command-list.txt +1 -0
@@ -218,6 +218,7 @@ gitcore-tutorial guide gitcredentials guide gitcvs-migration guide gitdatamodel guide +gitdetachedhead guide gitdiffcore guide giteveryday guide gitfaq guide
base-commit: 5a7d1e8045ce66c908f62598e26cbb8df7b39a90
Signature · 1 line
gitgitgadget
Documentation/detached-head.adoc line 5
Quoted 11 lines · Julia Evans via GitGitGadget
Documentation/detached-head.adoc new file +5
-0@@ -0,0 +1,43 @@ +`HEAD` is where Git stores your current branch. `HEAD` can either be: + +1. A branch, which is your current branch. +2. A commit ID, when you don't have a current branch. + This is called "detached HEAD state".
HEAD is branch which can either be a branch or something else?
HEAD records the state from which your current changes started. This can be a branch (the "current branch"), or it may not be associated with any concrete branch (in which case HEAD is "detached").
Documentation/detached-head.adoc line 9
Quoted 3 lines
Documentation/detached-head.adoc new file +3
-0+It can sometimes be useful for `HEAD` to be a commit ID. +For example, it lets you look at an old version of your code +(with `git checkout COMMIT_ID`).
To "look at" an older state is more versatile than simply running 'git show COMMIT_ID:path', as it allows you to do anything you can do on a branch, such as building and testing. Thus,
A detached HEAD is useful when you want to tentatively visit an old state with 'git checkout --detach v0.1', without having to create a dedicated branch for it.
Documentation/detached-head.adoc line 10
Quoted 2 lines
Documentation/detached-head.adoc new file +2
-0+The only problem is that if you create new commits while in detached +HEAD state, those commits won't be on a branch.
I would suggest rephrasing "The only problem" to "One caveat is" or something. When sightseeing and experimenting, the ability to create throw-away commits without the need to clean them up later, or to invent a unique name for a temporary branch, is not a problem. It is an advantage.
Documentation/detached-head.adoc line 16
Quoted 5 lines
This makes those new
Documentation/detached-head.adoc new file +4
-0+commits much harder to find later. Also, Git considers commits that +aren't on any branch (or a tag or other reference) to be garbage. +Git will eventually permanently delete those "garbage" commits during +garbage collection.
Correct.
Perhaps it is better to clarify this by adding "after you leave the detached HEAD state" after "to find later". While you are in the detached HEAD state, you can run 'git log' to find the commits you created there, as you can do everything you normally can on a branch, or use 'git reflog @{now}' for that matter.
Documentation/detached-head.adoc line 22
Quoted 5 lines
Documentation/detached-head.adoc new file +5
-0+There are 3 main ways you can end up in detached HEAD state +unintentionally: + +1. `git checkout COMMIT_ID`, where `COMMIT_ID` is a commit ID +2. `git checkout v1.3`, where v1.3 is a tag name
These I wouldn't call "unintentionally". They are documented and supported ways to do so, and will remain to be so. "unknowingly" may be a more fair way to call these gotchas, though.
Quoted 2 lines
+3.
git checkout origin/main, whereorigin/mainis
+ a remote-tracking branch
This can happen when the user forgets to say "-t" ('git checkout -t origin/main' dwims to 'git checkout -t -b main origin/main'), so it is closer to 'unintentionally' than the above two.
Documentation/detached-head.adoc line 28
Quoted 3 lines
Documentation/detached-head.adoc new file +3
-0+Checking out a tag puts you in detached HEAD state because `HEAD` can +only be a branch or a commit, not a tag or any other reference. +So `git checkout TAG` will set HEAD to the commit for that tag.
Correct.
Documentation/detached-head.adoc line 33
Quoted 4 lines
Documentation/detached-head.adoc new file +4
-0+The easiest way to avoid accidentally ending up in detached HEAD state +is to use linkgit:git-switch[1] instead of linkgit:git-checkout[1] to +switch branches. `git switch` won't let you detach unless you explicitly +pass the `--detach` argument.
Correct, but the motivation to 'avoid accidentally ending up' may want to be spelled out. Most often checking out a tag is to go sightseeing, where you do not want to 'avoid' detached HEAD.
Documentation/detached-head.adoc line 40
Quoted 6 lines
Documentation/detached-head.adoc new file +6
-0+To get back onto a branch, you can: + +1. Switch to the branch you want to be on, with `git switch BRANCHNAME`. +2. Create a new branch at the current commit, with `git switch -c BRANCHNAME`. + You might want to do this if you've created new commits, so that you can + find the commit later and so that it won't be garbage collected.
Very good.
Documentation/detached-head.adoc line 43
Quoted 2 lines
Documentation/detached-head.adoc new file +2
-0+If you create commits in detached HEAD state that aren't on a branch, +you can find them later using linkgit:git-reflog[1].
This, as you already said, is "much harder to find later" option. There should be a better recovery option described here before resorting to "git reflog HEAD" after you switched back. E.g.,
If you have created commits in detached HEAD state and then switched away from the state, all is not lost. "git checkout" would have give you a warning message, like this:
Warning: you are leaving 2 commits behind, not connected to any of your branches
c816689 typofix the previous 8e1bff5 decsribe detached HEAD state better
You can create branches to keep them, e.g., "git branch saved c816689", by using the commit object names left there.
Documentation/git-checkout.adoc For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. · line 379
Quoted 9 lines
Documentation/git-checkout.adoc +1
-0@@ -376,135 +376,8 @@ For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. [[DETACHED_HEAD]] DETACHED HEAD ------------- +include::detached-head.adoc[]
Losing the diagrams is a bit concerning. However, if the intention is to have readers learn how HEAD refers to a branch pointing at a commit with history structured as a DAG elsewhere in a more basic concepts guide, I suspect that it would actually work better. This could even be reduced to a simple "see also" pointer to that other guide.
If an existing user only uses 'switch' and never reads 'git help checkout', they are already not seeing these diagrams, or perhaps they learned the concepts elsewhere. They still manage to understand Git well enough to make use of it, so perhaps this approach is OK. I dunno.
Quoted 6 lines
Documentation/gitdetachedhead.adoc new file +0
-0
Documentation/gitdetachedhead.adoc line 10
Quoted 10 lines
Documentation/gitdetachedhead.adoc new file +10
-0@@ -0,0 +1,14 @@ +gitdetachedhead(7) +=============== + +NAME +---- +gitdetachedhead - How detached HEAD state works + +DESCRIPTION +----------- +include::detached-head.adoc[]
This may be good as a first step, but we may want to have more here than what we show in "git help checkout" later. If we miss the pictures we lost from "git help checkout", it can be moved here.
Thanks.
Quoted 30 lines
Documentation/gitdetachedhead.adoc new file +4
-0+ +GIT +--- +Part of the linkgit:git[1] suiteadvice.c +1
-0@@ -291,6 +291,7 @@ void detach_advice(const char *new_name)"\n" " git switch -\n" "\n" +"Run `git help detachedhead` to learn more.\n" "Turn off this advice by setting config variable advice.detachedHead to false\n\n");fprintf (stderr, fmt, new_name);command-list.txt +1
-0@@ -218,6 +218,7 @@ gitcore-tutorial guide gitcredentials guide gitcvs-migration guide gitdatamodel guide +gitdetachedhead guide gitdiffcore guide giteveryday guide gitfaq guidebase-commit:
5a7d1e8045ce66c908f62598e26cbb8df7b39a90
Quoted 1 line
Re: [PATCH] doc: checkout: rewrite detached HEAD state explanation
This change adds a standalone guide as well. The subject “just” make it sound like you are rewriting the text where it is.
Quoted 52 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
The current explanation has the following issues:
- Says detached HEAD state is useful but doesn't explain why
- Takes many paragraphs before explaining what detached HEAD state is
- It's common for users to accidentally end up in detached HEAD state, but it doesn't explain why that might happen
- One of the UI improvements ingit switchis to make it harder to detach accidentally, but that isn't advertised.
See7968bef06b(switch: only allow explicit detached HEAD, 2019-03-29)
- Too many confusing diagramsWrite a new explanation addressing these issues, and put it in a standalone guide so that we can easily reference it from advice ("see
git help detachedhead").
The result is a shorter guide that covers more material.The framing that "Git considers commits that aren't on a branch/other reference to be garbage" is taken from Steve Klabnik's tutorial
https://steveklabnik.github.io/jujutsu-tutorial/branching-merging-and-conflicts/anonymous-branches.html.
It's funny and it's consistent with the way Git uses the term "garbage collection".Co-authored-by Marie Claire LeBlanc Flanagan <[email protected]>Signed-off-by Julia Evans <[email protected]>---
doc: checkout: rewrite detached HEAD state explanationOften when rewriting these explanations I go through a process where I ask users' feedback on the old explanation. Here I didn't do that basically because that process takes a long time and I'm working on a bunch of other time consuming docs projects so I did a quick rewrite based on my previous experience explaining detached HEAD state to folks.
I thought this could be a nice quick docs win on a topic which many users find quite confusing. If the changes here are too controversial I can drop it for now.
Also if folks object to making a separate git help detachedhead guide I'm happy to drop that too. Personally I'm excited about the idea of being able to reference the guides in our advice (which is one of our best tools for getting users info about how to use Git!), but it's not possible to let users jump to a subsection, so this is sort of a hack around that.
Published-As:
https://github.com/gitgitgadget/git/releases/tag/pr-2250%2Fjvns%2Fdetached-head-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git
pr-2250/jvns/detached-head-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/2250
Quoted 3 lines
Documentation/detached-head.adoc | 43 ++++++++++ Documentation/git-checkout.adoc | 129 +---------------------------- Documentation/gitdetachedhead.adoc | 14 ++++
Why in one word instead of hyphenating detached-head? (gitdetached-head(7))
Quoted 2 lines
advice.c | 1 + command-list.txt | 1 +
This is missing meson/Makefile changes in order to make gitdetachedhead(7).
Documentation/detached-head.adoc line 1
Quoted 12 lines
5 files changed, 60 insertions(+), 128 deletions(-) create mode 100644 Documentation/detached-head.adoc create mode 100644 Documentation/gitdetachedhead.adocDocumentation/detached-head.adoc new file +1
-0@@ -0,0 +1,43 @@ +`HEAD` is where Git stores your current branch. `HEAD` can either be:
I see that this is similar to gitdatamodel(7). Except it adds “, if there is a current branch”:
HEAD is where Git stores your current branch, if there is a current branch. HEAD can either be: [...]
But a potential problem with that is:
A: What is HEAD?
B: It stores the current branch, if there is a current branch.
A: Oh so it is *empty* if there is no current branch?
B: No. Then it stores a commit.
This is of course revealed later here. But I wonder if starting with current-branch can set someone up for a double take.
One could go in the other direction: you are almost always on a commit. For most people the exception will be the unborn branch state after git init. That commit is stored in the thing called HEAD. And if you are on branch it also points to that branch. (It doesn’t point at two things at the same time but instead at the branch, which is in turn points at the commit for the branch, but conceptually it’s the same difference).
Documentation/detached-head.adoc line 9
Quoted 8 lines
Documentation/detached-head.adoc new file +8
-0+ +1. A branch, which is your current branch. +2. A commit ID, when you don't have a current branch. + This is called "detached HEAD state". + +It can sometimes be useful for `HEAD` to be a commit ID. +For example, it lets you look at an old version of your code +(with `git checkout COMMIT_ID`).
Maybe go straight to git switch --detached COMMIT_ID here.
It is very useful to describe detached HEAD as something that you can fall into by accident. It is very much perenially needed. And this paragraph explains a legitimate, intentional use.
But a dedicated guide is also an opportunity to not only acknowledge hey there is a use here but to explain actively why it is convenient. Because one thing is “detached HEAD” as a conceptual, scary blind alley where my work might get garbage collected. But only thinking in terms of branches and tags can lead to a dead end of only thinking of Git as:
1. The state of our collective work right now (“main”)
2. Our important waypoints (tags)
So before you lead them out of the maw of the garbage incinerator, you can help level up their use of Git by explaining why checking out commits freely is useful with an example of why they would do that.
1. Finding buggy commits manually (this would probably end with a mention of git-bisect(1))
2. Testing that each commit on a branch (forked from main) passes the test suite
3. Browsing an interesting commit manually instead of pointing git grep at the commit (or something)
4. Just being on origin/main instead of having a main. I never update “main”. So why would I go to the trouble of keeping it up to date? I can just “be on” origin/main (detached on whatever that points to).
See also StackOverflow questions about how to update hundreds of local branches with git-pull(1) or something. Why? They do not have hundreds of local branches that they are authoring. They just want those branches by other people to be updated. But that is not necessary for anything. You just need the remote-tracking branches. Including if you want to check them out (on detached HEAD).
This conceptual dead end (of no “detached HEAD) could manifest itself like this:
• “I must always be on a branch”
• “Therefore I can only check out old commits by first creating a branch”
• “Every interesting commit must have a tag for posteriety so we can name it” (you just need the hash, even abbreviated)
• “We must tag this commit for the build so we can name the build” (you can just use the hash or use part-of-the-hash with git-describe(1))
Documentation/detached-head.adoc line 16
Quoted 7 lines
Documentation/detached-head.adoc new file +7
-0+ +The only problem is that if you create new commits while in detached +HEAD state, those commits won't be on a branch. This makes those new +commits much harder to find later. Also, Git considers commits that +aren't on any branch (or a tag or other reference) to be garbage. +Git will eventually permanently delete those "garbage" commits during +garbage collection.
Maybe this is where you should mention git-reflog(1) (and git-log(1) maybe (see later)).
Maybe this about garbage collection could be tempered with a mention of the however-many default days for reflog expiry. It’s such a long time that if any of my commits get garbage collected... I probably didn’t need them.
Documentation/detached-head.adoc line 19
Quoted 3 lines
Documentation/detached-head.adoc new file +3
-0+ +There are 3 main ways you can end up in detached HEAD state +unintentionally:
I would say “typical” instead of “main”. As in these things are the typical gateways to this state (unintentionally).
Documentation/detached-head.adoc line 28
Quoted 9 lines
Documentation/detached-head.adoc new file +9
-0+ +1. `git checkout COMMIT_ID`, where `COMMIT_ID` is a commit ID +2. `git checkout v1.3`, where v1.3 is a tag name +3. `git checkout origin/main`, where `origin/main` is + a remote-tracking branch + +Checking out a tag puts you in detached HEAD state because `HEAD` can +only be a branch or a commit, not a tag or any other reference. +So `git checkout TAG` will set HEAD to the commit for that tag.
Nice.
Quoted 6 lines
Documentation/detached-head.adoc new file +4
-0+ +The easiest way to avoid accidentally ending up in detached HEAD state +is to use linkgit:git-switch[1] instead of linkgit:git-checkout[1] to +switch branches. `git switch` won't let you detach unless youexplicitly
Documentation/detached-head.adoc new file +1
-0+pass the `--detach` argument.
Documentation/detached-head.adoc line 43
Quoted 10 lines
Documentation/detached-head.adoc new file +10
-0+ +To get back onto a branch, you can: + +1. Switch to the branch you want to be on, with `git switch BRANCHNAME`. +2. Create a new branch at the current commit, with `git switch -c BRANCHNAME`. + You might want to do this if you've created new commits, so that you can + find the commit later and so that it won't be garbage collected. + +If you create commits in detached HEAD state that aren't on a branch, +you can find them later using linkgit:git-reflog[1].
Okay, but it’s more immediate and obvious to use git log. Say you created three commits by accident while not on a branch. Then they will be immediately um logged.
git-reflog(1) is excellent too of course, mostly because you are likely to find all of them if you did a lot of weird checkouts in one session.
Documentation/git-checkout.adoc For more details, see the 'pathspec' entry in
Quoted 7 lines
Documentation/git-checkout.adoc +0
-0@@ -376,135 +376,8 @@ For more details, see the 'pathspec' entry in
I didn’t read the rest here.
To make this process easier, I'm going to first deal with factual issues (like any mistakes or ideas for more information content to include). I'll mark comments that are suggestions for how to make the wording more clear with "style comment" to potentially address later.
Quoted 4 lines · Kristoffer Haugsbakk
Quoted 1 line
Re: [PATCH] doc: checkout: rewrite detached HEAD state explanation
This change adds a standalone guide as well. The subject “just” make it sound like you are rewriting the text where it is.
Yes. I ran out of space while writing the subject line. Happy to make changes to how the commit is structured if that would be better.
Quoted 6 lines
Quoted 3 lines
Documentation/detached-head.adoc | 43 ++++++++++ Documentation/git-checkout.adoc | 129 +---------------------------- Documentation/gitdetachedhead.adoc | 14 ++++Why in one word instead of hyphenating
detached-head? (gitdetached-head(7))
Currently the guides are all one word with no hyphens. Happy to use a different style if folks think we shouldn't use the current naming convention for the guides
Quoted 5 lines
Quoted 2 lines
advice.c | 1 + command-list.txt | 1 +This is missing meson/Makefile changes in order to make gitdetachedhead(7).
Thanks, will fix.
Quoted 14 lines
Quoted 12 lines
5 files changed, 60 insertions(+), 128 deletions(-) create mode 100644 Documentation/detached-head.adoc create mode 100644 Documentation/gitdetachedhead.adocDocumentation/detached-head.adoc new file +1
-0@@ -0,0 +1,43 @@ +`HEAD` is where Git stores your current branch. `HEAD` can either be:
Quoted 10 lines
Documentation/detached-head.adoc line 9
Quoted 8 lines
Documentation/detached-head.adoc new file +8
-0+ +1. A branch, which is your current branch. +2. A commit ID, when you don't have a current branch. + This is called "detached HEAD state". + +It can sometimes be useful for `HEAD` to be a commit ID. +For example, it lets you look at an old version of your code +(with `git checkout COMMIT_ID`).Maybe go straight to
git switch --detached COMMIT_IDhere.
Style comment.
Quoted 18 lines
It is very useful to describe detached
HEADas something that you can fall into by accident. It is very much perenially needed. And this paragraph explains a legitimate, intentional use.But a dedicated guide is also an opportunity to not only acknowledge hey there is a use here but to explain actively why it is convenient. Because one thing is “detached
HEAD” as a conceptual, scary blind alley where my work might get garbage collected. But only thinking in terms of branches and tags can lead to a dead end of only thinking of Git as:1. The state of our collective work right now (“main”)
2. Our important waypoints (tags)So before you lead them out of the maw of the garbage incinerator, you can help level up their use of Git by explaining why checking out commits freely is useful with an example of why they would do that.
Quoted 10 lines
1. Finding buggy commits manually (this would probably end with a mention of git-bisect(1))
2. Testing that each commit on a branch (forked frommain) passes the test suite
3. Browsing an interesting commit manually instead of pointinggit grepat the commit (or something)
4. Just being onorigin/maininstead of having amain. I never update “main”. So why would I go to the trouble of keeping it up to date? I can just “be on”origin/main(detached on whatever that points to).
This is a nice list of reasons being in detached head state, thanks. Not sure if it will be helpful to include or not though.
Quoted 29 lines
See also StackOverflow questions about how to update hundreds of local branches with git-pull(1) or something. Why? They do not have hundreds of local branches that they are authoring. They just want those branches by other people to be updated. But that is not necessary for anything. You just need the remote-tracking branches. Including if you want to check them out (on detached
HEAD).This conceptual dead end (of no “detached
HEAD) could manifest itself like this:• “I must always be on a branch”
• “Therefore I can only check out old commits by first creating a branch”
• “Every interesting commit must have a tag for posteriety so we can name it” (you just need the hash, even abbreviated)
• “We must tag this commit for the build so we can name the build” (you can just use the hash or use part-of-the-hash with git-describe(1))Documentation/detached-head.adoc line 16
Quoted 6 lines
Documentation/detached-head.adoc new file +6
-0+The only problem is that if you create new commits while in detached +HEAD state, those commits won't be on a branch. This makes those new +commits much harder to find later. Also, Git considers commits that +aren't on any branch (or a tag or other reference) to be garbage. +Git will eventually permanently delete those "garbage" commits during +garbage collection.Maybe this is where you should mention git-reflog(1) (and git-log(1) maybe (see later)).
Quoted 4 lines
Maybe this about garbage collection could be tempered with a mention of the however-many default days for reflog expiry. It’s such a long time that if any of my commits get garbage collected... I probably didn’t need them.
Good idea, will mention it's 90 days by default.
Quoted 6 lines
Documentation/detached-head.adoc line 19
Quoted 3 lines
Documentation/detached-head.adoc new file +3
-0+ +There are 3 main ways you can end up in detached HEAD state +unintentionally:I would say “typical” instead of “main”. As in these things are the typical gateways to this state (unintentionally).
Style comment
Quoted 21 lines
Quoted 6 lines
Documentation/detached-head.adoc new file +4
-0+ +The easiest way to avoid accidentally ending up in detached HEAD state +is to use linkgit:git-switch[1] instead of linkgit:git-checkout[1] to +switch branches. `git switch` won't let you detach unless youexplicitly
Documentation/detached-head.adoc new file +1
-0+pass the `--detach` argument.Documentation/detached-head.adoc line 43
Quoted 10 lines
Documentation/detached-head.adoc new file +10
-0+ +To get back onto a branch, you can: + +1. Switch to the branch you want to be on, with `git switch BRANCHNAME`. +2. Create a new branch at the current commit, with `git switch -c BRANCHNAME`. + You might want to do this if you've created new commits, so that you can + find the commit later and so that it won't be garbage collected. + +If you create commits in detached HEAD state that aren't on a branch, +you can find them later using linkgit:git-reflog[1].Okay, but it’s more immediate and obvious to use
git log. Say you created three commits by accident while not on a branch. Then they will be immediately um logged.
Quoted 2 lines
git-reflog(1) is excellent too of course, mostly because you are likely to find all of them if you did a lot of weird checkouts in one session.
Going to deal with this another way
Quoted 6 lines · Julia Evans
Quoted 5 lines · Kristoffer Haugsbakk
Quoted 4 lines
[snip]
Documentation/detached-head.adoc | 43 ++++++++++ Documentation/git-checkout.adoc | 129 +---------------------------- Documentation/gitdetachedhead.adoc | 14 ++++
Quoted 6 lines
Quoted 2 lines
Why in one word instead of hyphenating
detached-head? (gitdetached-head(7))Currently the guides are all one word with no hyphens. Happy to use a different style if folks think we shouldn't use the current naming convention for the guides
I’m confused. It doesn’t look like that to me?
$ git help --guides
The Git concept guides are:
core-tutorial A Git core tutorial for developers
credentials Providing usernames and passwords to Git
cvs-migration Git for CVS users
diffcore Tweaking diff output
everyday A useful minimum set of commands for Everyday Git
faq Frequently asked questions about using Git
glossary A Git Glossary
namespaces Git namespaces
remote-helpers Helper programs to interact with remote repositories
submodules Mounting one repository inside another
tutorial A tutorial introduction to Git
tutorial-2 A tutorial introduction to Git: part two
workflows An overview of recommended workflows with Git 'git help -a' and 'git help -g' list available subcommands and some concept guides. See 'git help <command>' or 'git help <concept>' to read about a specific subcommand or concept.
See 'git help git' for an overview of the system.
What is definitely the case is that there is no hyphen between git and the first word, maybe in order to distinguish section 1 commands) and section 5 and 7 manpages.
Quoted 2 lines
[snip]
Quoted 32 lines · Kristoffer Haugsbakk
Quoted 6 lines · Julia Evans
Quoted 5 lines · Kristoffer Haugsbakk
Quoted 4 lines
[snip]
Documentation/detached-head.adoc | 43 ++++++++++ Documentation/git-checkout.adoc | 129 +---------------------------- Documentation/gitdetachedhead.adoc | 14 ++++Quoted 6 lines
Quoted 2 lines
Why in one word instead of hyphenating
detached-head? (gitdetached-head(7))Currently the guides are all one word with no hyphens. Happy to use a different style if folks think we shouldn't use the current naming convention for the guides
I’m confused. It doesn’t look like that to me?
$ git help --guides The Git concept guides are: core-tutorial A Git core tutorial for developers credentials Providing usernames and passwords to Git cvs-migration Git for CVS users diffcore Tweaking diff output everyday A useful minimum set of commands for Everyday Git faq Frequently asked questions about using Git glossary A Git Glossary namespaces Git namespaces remote-helpers Helper programs to interact with remote repositories submodules Mounting one repository inside another tutorial A tutorial introduction to Git tutorial-2 A tutorial introduction to Git: part two workflows An overview of recommended workflows with Git
Quoted 8 lines
'git help -a' and 'git help -g' list available subcommands and some concept guides. See 'git help <command>' or 'git help <concept>' to read about a specific subcommand or concept.
See 'git help git' for an overview of the system.What is definitely the case is that there is no hyphen between
gitand the first word, maybe in order to distinguish section 1 commands) and section 5 and 7 manpages.
Thanks, I'll change the naming, I didn't realize that. For some reason I felt sure it was the other way. Maybe we should rename gitmergeconflicts to gitmerge-conflicts in the other patch series too.
My best guess is that I made that mistake because I (maybe idiosyncratically) always use man <page> to access the Git man pages, and typing man gitdetached-head feels awkward to me.
But of course we're recommending that folks use git help detached-head, and git help detached-head is much nicer than git help detachedhead.
Quoted 8 lines
Quoted 3 lines
What is definitely the case is that there is no hyphen between
gitand the first word, maybe in order to distinguish section 1 commands) and section 5 and 7 manpages.Thanks, I'll change the naming, I didn't realize that. For some reason I felt sure it was the other way. Maybe we should rename
gitmergeconflictstogitmerge-conflictsin the other patch series too.
Quoted 5 lines
My best guess is that I made that mistake because I (maybe idiosyncratically) always use
man <page>to access the Git man pages, and typingman gitdetached-headfeels awkward to me.
But of course we're recommending that folks usegit help detached-head, andgit help detached-headis much nicer thangit help detachedhead.
Reflecting on this a little more, I think there's a bit of a disconnect between how we recommend users use the Git help system (via git help config) and how we refer to other man pages in the man pages, which is like this:
Quoted 1 line
(see git-fetch(1), git-config(1) and gitmodules(5))
If a user sees a reference like git-config(1) or gitmodules(5), the most obvious way to look it up is to type man git-config, or man gitmodules and not to deduce that you can rungit help config or git help modules: Especially because sometimes you need to remove a git- from the beginning and sometimes just git. I'm don't think the git-help man page even explains how those prefixes work.
So at some point if we want to really encourage people to use git help instead of man we might want to revisit how we present the internal references in the man pages.
Obviously not something to solve right now, and I don't know what a good solution would be.
Thanks for the review. I'm going to mark comments that I feel are about style issues (like "could this be explained in a more clear way?") as just "style comment" to deal with later.
In general if we really want to make sure that this is as clear as possible, I think it would be most effective to do a second revision later (after merging this) where we get feedback from users and find out what folks are confused by.
Quoted 15 lines · Junio C Hamano
Documentation/detached-head.adoc line 5
Quoted 11 lines · Julia Evans via GitGitGadget
Documentation/detached-head.adoc new file +5
-0@@ -0,0 +1,43 @@ +`HEAD` is where Git stores your current branch. `HEAD` can either be: + +1. A branch, which is your current branch. +2. A commit ID, when you don't have a current branch. + This is called "detached HEAD state".HEAD is branch which can either be a branch or something else?
Style comment. Probably this is the one I'd prioritize the highest.
Quoted 12 lines
HEAD records the state from which your current changes started. This can be a branch (the "current branch"), or it may not be associated with any concrete branch (in which case HEAD is "detached")
Documentation/detached-head.adoc line 9
Quoted 3 lines
Documentation/detached-head.adoc new file +3
-0+It can sometimes be useful for `HEAD` to be a commit ID. +For example, it lets you look at an old version of your code +(with `git checkout COMMIT_ID`).To "look at" an older state is more versatile than simply running 'git show COMMIT_ID:path', as it allows you to do anything you can do on a branch, such as building and testing. Thus,
Quoted 3 lines
A detached HEAD is useful when you want to tentatively visit an old state with 'git checkout --detach v0.1', without having to create a dedicated branch for it.
Style comment.
Quoted 8 lines
Documentation/detached-head.adoc line 10
Quoted 2 lines
Documentation/detached-head.adoc new file +2
-0+The only problem is that if you create new commits while in detached +HEAD state, those commits won't be on a branch.I would suggest rephrasing "The only problem" to "One caveat is" or something. When sightseeing and experimenting, the ability to create throw-away commits without the need to clean them up later, or to invent a unique name for a temporary branch, is not a problem. It is an advantage.
Style comment.
Quoted 14 lines
Documentation/detached-head.adoc line 16
Quoted 5 lines
This makes those new
Documentation/detached-head.adoc new file +4
-0+commits much harder to find later. Also, Git considers commits that +aren't on any branch (or a tag or other reference) to be garbage. +Git will eventually permanently delete those "garbage" commits during +garbage collection.Correct.
Perhaps it is better to clarify this by adding "after you leave the detached HEAD state" after "to find later". While you are in the detached HEAD state, you can run 'git log' to find the commits you created there, as you can do everything you normally can on a branch, or use 'git reflog @{now}' for that matter.
Quoted 9 lines
Documentation/detached-head.adoc line 22
Quoted 5 lines
Documentation/detached-head.adoc new file +5
-0+There are 3 main ways you can end up in detached HEAD state +unintentionally: + +1. `git checkout COMMIT_ID`, where `COMMIT_ID` is a commit ID +2. `git checkout v1.3`, where v1.3 is a tag nameThese I wouldn't call "unintentionally". They are documented and supported ways to do so, and will remain to be so. "unknowingly" may be a more fair way to call these gotchas, though.
Thanks, removed "unintentionally".
Quoted 9 lines
Documentation/detached-head.adoc line 33
Quoted 5 lines
Documentation/detached-head.adoc new file +4
-0+The easiest way to avoid accidentally ending up in detached HEAD state +is to use linkgit:git-switch[1] instead of linkgit:git-checkout[1] to +switch branches. `git switch` won't let you detach unless you explicitly +pass the `--detach` argument.Correct, but the motivation to 'avoid accidentally ending up' may want to be spelled out. Most often checking out a tag is to go sightseeing, where you do not want to 'avoid' detached HEAD.
Style comment.
Quoted 20 lines
Documentation/detached-head.adoc line 40
Quoted 6 lines
Documentation/detached-head.adoc new file +6
-0+To get back onto a branch, you can: + +1. Switch to the branch you want to be on, with `git switch BRANCHNAME`. +2. Create a new branch at the current commit, with `git switch -c BRANCHNAME`. + You might want to do this if you've created new commits, so that you can + find the commit later and so that it won't be garbage collected.Very good.
Documentation/detached-head.adoc line 43
Quoted 2 lines
Documentation/detached-head.adoc new file +2
-0+If you create commits in detached HEAD state that aren't on a branch, +you can find them later using linkgit:git-reflog[1].This, as you already said, is "much harder to find later" option. There should be a better recovery option described here before resorting to "git reflog HEAD" after you switched back. E.g.,
If you have created commits in detached HEAD state and then switched away from the state, all is not lost. "git checkout" would have give you a warning message, like this:
Quoted 8 lines
Warning: you are leaving 2 commits behind, not connected to any of your branches
c816689 typofix the previous 8e1bff5 decsribe detached HEAD state better
You can create branches to keep them, e.g., "git branch saved c816689", by using the commit object names left there.
Thanks, added a mention of this warning. It's a really nice example of the ways Git helps avoid issues.
Quoted 17 lines
Documentation/git-checkout.adoc For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. · line 379
Quoted 9 lines
Documentation/git-checkout.adoc +1
-0@@ -376,135 +376,8 @@ For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. [[DETACHED_HEAD]] DETACHED HEAD ------------- +include::detached-head.adoc[]Losing the diagrams is a bit concerning. However, if the intention is to have readers learn how HEAD refers to a branch pointing at a commit with history structured as a DAG elsewhere in a more basic concepts guide, I suspect that it would actually work better. This could even be reduced to a simple "see also" pointer to that other guide.
Quoted 5 lines
If an existing user only uses 'switch' and never reads 'git help checkout', they are already not seeing these diagrams, or perhaps they learned the concepts elsewhere. They still manage to understand Git well enough to make use of it, so perhaps this approach is OK. I dunno.
Thanks, good idea to give people a pointer to more info about HEAD. I'll try adding a pointer to git help datamodel.
I'm not against adding diagrams, but I think if we want to add diagrams that should be a separate project where we actually get feedback from users. Similarly for explaining HEAD in more detail.
PATCH v2 1/1 doc: checkout: rewrite detached HEAD state explanation
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
The current explanation has the following issues:
- Says detached HEAD state is useful but doesn't explain why
- Takes many paragraphs before explaining what detached HEAD state is
- It's common for users to accidentally end up in detached HEAD state, but it doesn't explain why that might happen
- One of the UI improvements in git switch is to make it harder to detach accidentally, but that isn't advertised.
See 7968bef06b (switch: only allow explicit detached HEAD, 2019-03-29)
- Too many confusing diagrams
Write a new explanation addressing these issues, and put it in a standalone guide so that we can easily reference it from advice ("see git help detachedhead").
The result is a shorter guide that covers more material.
The framing that "Git considers commits that aren't on a branch/other reference to be garbage" is taken from Steve Klabnik's tutorial
https://steveklabnik.github.io/jujutsu-tutorial/branching-merging-and-conflicts/anonymous-branches.html.
It's funny and it's consistent with the way Git uses the term "garbage collection".
---
doc: checkout: rewrite detached HEAD state explanation
This is a pretty quick rewrite where we didn't get any user feedback. If we really want to make sure it's clear to users as possible, we should IMO do a second stage later where we ask users which parts are unclear.
Changes in v2:
* Make the meson.build and Makefile changes (thanks to Kristoffer)
* Rename to gitdata-model (thanks to Kristoffer)
* Mention commits will be deleted after 90 days to make it seem less scary (thanks to Kristoffer)
* Add an "easily" qualifier to "it lets you look at an old version of your code", to avoid implying that this is the only way (thanks to Junio)
* Mention that Git will warn you when switching branches if you're leaving commits behind (thanks to Junio)
* Remove "unintentionally" (thanks to Junio)
* Mention git help datamodel (thanks to Junio)
Left the style comments alone (ideas for how to make it more clear) to be potentially addressed in v3, after we finalize the information content.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2250%2Fjvns%2Fdetached-head-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2250/jvns/detached-head-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/2250
Range-diff vs v1:
1: efe0f9db36 ! 1: 83139be46f doc: checkout: rewrite detached HEAD state explanation
@@ Commit message
+ ## Documentation/Makefile ##
+@@ Documentation/Makefile: MAN7_TXT += gitcore-tutorial.adoc
+ MAN7_TXT += gitcredentials.adoc
+ MAN7_TXT += gitcvs-migration.adoc
+ MAN7_TXT += gitdatamodel.adoc
++MAN7_TXT += gitdetached-head.adoc
+ MAN7_TXT += gitdiffcore.adoc
+ MAN7_TXT += giteveryday.adoc
+ MAN7_TXT += gitfaq.adoc
+
## Documentation/detached-head.adoc (new) ##
@@
+HEAD is where Git stores your current branch. HEAD can either be:
@@ Documentation/detached-head.adoc (new)
+ This is called "detached HEAD state".
+
+It can sometimes be useful for HEAD to be a commit ID.
-+For example, it lets you look at an old version of your code -+(with git checkout COMMIT_ID).
++For example, it lets you easily look at an old version of your code ++(with git checkout COMMIT_ID or git switch --detach COMMIT_ID).
+
+The only problem is that if you create new commits while in detached +HEAD state, those commits won't be on a branch. This makes those new +commits much harder to find later. Also, Git considers commits that +aren't on any branch (or a tag or other reference) to be garbage. +Git will eventually permanently delete those "garbage" commits during
-+garbage collection.
++garbage collection. Those commits will be deleted after 90 days by ++default, see linkgit:git-gc[1] for more.
+
-+There are 3 main ways you can end up in detached HEAD state -+unintentionally:
++There are 3 main ways you can end up in detached HEAD state:
+
+1. git checkout COMMIT_ID, where COMMIT_ID is a commit ID +2. git checkout v1.3, where v1.3 is a tag name
@@ Documentation/detached-head.adoc (new)
+ You might want to do this if you've created new commits, so that you can
+ find the commit later and so that it won't be garbage collected.
+
-+If you create commits in detached HEAD state that aren't on a branch, -+you can find them later using linkgit:git-reflog[1].
++If you switch branches after making commits in detached HEAD state, Git ++will warn you that you might be about to "lose" those commits and print ++out the commit ID. You can also always find those commits later using ++linkgit:git-reflog[1].
++
++Here's what that warning looks like:
++
++-------------------------
++Warning: you are leaving 1 commit behind, not connected to ++any of your branches:
++
++ 48c09f6 3
++-------------------------
++
++For a more in-depth explanation of how HEAD works in Git, ++see linkgit:gitdatamodel[7] (git help datamodel).
## Documentation/git-checkout.adoc ##
@@ Documentation/git-checkout.adoc: For more details, see the 'pathspec' entry in linkgit:gitglossary[7].
@@ Documentation/git-checkout.adoc: For more details, see the 'pathspec' entry in l
[[ARGUMENT_DISAMBIGUATION]]
ARGUMENT DISAMBIGUATION
- ## Documentation/gitdetachedhead.adoc (new) ##
+ ## Documentation/gitdetached-head.adoc (new) ## @@
-+gitdetachedhead(7)
-+===============
++gitdetached-head(7)
++===================
+
+NAME
+----
-+gitdetachedhead - How detached HEAD state works ++gitdetached-head - How detached HEAD state works
+
+DESCRIPTION
+-----------
@@ Documentation/gitdetachedhead.adoc (new)
+---
+Part of the linkgit:git[1] suite
+ ## Documentation/meson.build ##
+@@ Documentation/meson.build: manpages = {
+ 'gitcredentials.adoc' : 7,
+ 'gitcvs-migration.adoc' : 7,
+ 'gitdatamodel.adoc' : 7,
++ 'gitdetached-head.adoc' : 7,
+ 'gitdiffcore.adoc' : 7,
+ 'giteveryday.adoc' : 7,
+ 'gitfaq.adoc' : 7,
+
## advice.c ##
@@ advice.c: void detach_advice(const char *new_name)
"\n"
@@ command-list.txt: gitcore-tutorial guide
gitcredentials guide
gitcvs-migration guide
gitdatamodel guide
-+gitdetachedhead guide
++gitdetached-head guide
gitdiffcore guide
giteveryday guide
gitfaq guide
Documentation/Makefile | 1 + Documentation/detached-head.adoc | 57 ++++++++++++ Documentation/git-checkout.adoc | 129 +--------------------------- Documentation/gitdetached-head.adoc | 14 +++ Documentation/meson.build | 1 + advice.c | 1 + command-list.txt | 1 + 7 files changed, 76 insertions(+), 128 deletions(-) create mode 100644 Documentation/detached-head.adoc create mode 100644 Documentation/gitdetached-head.adoc
Documentation/Makefile +1 -0
@@ -54,6 +54,7 @@ MAN7_TXT += gitcore-tutorial.adoc MAN7_TXT += gitcredentials.adoc MAN7_TXT += gitcvs-migration.adoc MAN7_TXT += gitdatamodel.adoc +MAN7_TXT += gitdetached-head.adoc MAN7_TXT += gitdiffcore.adoc MAN7_TXT += giteveryday.adoc MAN7_TXT += gitfaq.adoc
Documentation/detached-head.adoc new file +57 -0
57 lines not on this page · raw message
Documentation/git-checkout.adoc +1 -128
136 lines not on this page · raw message
Documentation/gitdetached-head.adoc new file +14 -0
@@ -0,0 +1,14 @@ +gitdetached-head(7) +=================== + +NAME +---- +gitdetached-head - How detached HEAD state works + +DESCRIPTION +----------- +include::detached-head.adoc[] + +GIT +--- +Part of the linkgit:git[1] suite
Documentation/meson.build +1 -0
@@ -197,6 +197,7 @@ manpages = { 'gitcredentials.adoc' : 7, 'gitcvs-migration.adoc' : 7, 'gitdatamodel.adoc' : 7, + 'gitdetached-head.adoc' : 7, 'gitdiffcore.adoc' : 7, 'giteveryday.adoc' : 7, 'gitfaq.adoc' : 7,
advice.c +1 -0
@@ -291,6 +291,7 @@ void detach_advice(const char *new_name)"\n" " git switch -\n" "\n" +"Run `git help detachedhead` to learn more.\n" "Turn off this advice by setting config variable advice.detachedHead to false\n\n");fprintf (stderr, fmt, new_name);
command-list.txt +1 -0
@@ -218,6 +218,7 @@ gitcore-tutorial guide gitcredentials guide gitcvs-migration guide gitdatamodel guide +gitdetached-head guide gitdiffcore guide giteveryday guide gitfaq guide
base-commit: 5a7d1e8045ce66c908f62598e26cbb8df7b39a90
Signature · 1 line
gitgitgadget
Quoted 3 lines · Julia Evans via GitGitGadget
Write a new explanation addressing these issues, and put it in a standalone guide so that we can easily reference it from advice ("see
git help detachedhead").
Isn't it 'git help detached-head' in this edition?
Quoted 2 lines
Co-authored-by Marie Claire LeBlanc Flanagan <[email protected]>Signed-off-by Julia Evans <[email protected]>
Can the other author also sign it off?
Documentation/detached-head.adoc line 17
Quoted 3 lines
Documentation/detached-head.adoc new file +3
-0+Git will eventually permanently delete those "garbage" commits during +garbage collection. Those commits will be deleted after 90 days by +default, see linkgit:git-gc[1] for more.
Does this say 90 days because that is the gc.reflogExpire retention?
If you create a commit, change your mind, rewind the tip of the branch (e.g., with "git commit --amend"), and then keep working, the original commit before amending would be unreachable from the tip of that branch. Its reflog entry would then expire after gc.reflogExpireUnreachable, which defaults to 30 days. If your commit were created on a detached HEAD, I am not sure offhand how the thresholds for gc.reflogExpire and gc.reflogExpireUnreachable come into play for HEAD, as HEAD by default flips back and forth regularly across branch tips that are not reachable from each other. When "gc" kicks in, the commit HEAD currently points to is unlikely to reach the abandoned commit.
It might be safer to either say "after 30 days by default" or generalize it to "after a few weeks by default" to avoid being overly prescriptive.
advice.c void detach_advice(const char *new_name) · line 294
Quoted 9 lines
advice.c +1
-0@@ -291,6 +291,7 @@ void detach_advice(const char *new_name)"\n" " git switch -\n" "\n" +"Run `git help detachedhead` to learn more.\n"
"git help deatched-head" here, too.
command-list.txt gitcore-tutorial guide · line 224
Quoted 13 lines
advice.c +0
-0fprintf (stderr, fmt, new_name);command-list.txt +1
-0@@ -218,6 +218,7 @@ gitcore-tutorial guide gitcredentials guide gitcvs-migration guide gitdatamodel guide +gitdetached-head guide gitdiffcore guide giteveryday guide gitfaq guide
This seems to be manually aligned with SP, so compensate the addition of "-" between detached and head by removing one SP before guide on the same line.
Thanks.
Quoted 7 lines · Junio C Hamano
Quoted 3 lines · Julia Evans via GitGitGadget
Write a new explanation addressing these issues, and put it in a standalone guide so that we can easily reference it from advice ("see
git help detachedhead").Isn't it 'git help detached-head' in this edition?
Will fix.
Quoted 4 lines
Quoted 2 lines
Co-authored-by Marie Claire LeBlanc Flanagan <[email protected]>Signed-off-by Julia Evans <[email protected]>Can the other author also sign it off?
Will do.
Quoted 5 lines
Documentation/detached-head.adoc line 17
Quoted 3 lines
Documentation/detached-head.adoc new file +3
-0+Git will eventually permanently delete those "garbage" commits during +garbage collection. Those commits will be deleted after 90 days by +default, see linkgit:git-gc[1] for more.Does this say 90 days because that is the gc.reflogExpire retention?
Yes, I wasn't sure how it works exactly.
Quoted 12 lines
If you create a commit, change your mind, rewind the tip of the branch (e.g., with "git commit --amend"), and then keep working, the original commit before amending would be unreachable from the tip of that branch. Its reflog entry would then expire after gc.reflogExpireUnreachable, which defaults to 30 days. If your commit were created on a detached HEAD, I am not sure offhand how the thresholds for gc.reflogExpire and gc.reflogExpireUnreachable come into play for HEAD, as HEAD by default flips back and forth regularly across branch tips that are not reachable from each other. When "gc" kicks in, the commit HEAD currently points to is unlikely to reach the abandoned commit.
Quoted 3 lines
It might be safer to either say "after 30 days by default" or generalize it to "after a few weeks by default" to avoid being overly prescriptive.
Will change to "30 days", I think "30 days" makes it a tiny bit easier for someone to figure out where that number might come from.
Quoted 11 lines
advice.c void detach_advice(const char *new_name) · line 294
Quoted 9 lines
advice.c +1
-0@@ -291,6 +291,7 @@ void detach_advice(const char *new_name)"\n" " git switch -\n" "\n" +"Run `git help detachedhead` to learn more.\n" "git help deatched-head" here, too.
Will do.
Quoted 9 lines
Quoted 9 lines
advice.c +0
-0fprintf (stderr, fmt, new_name);command-list.txt +0
-0@@ -218,6 +218,7 @@ gitcore-tutorial guide gitcredentials guide gitcvs-migration guide gitdatamodel guide
Quoted 8 lines
command-list.txt gitcore-tutorial guide · line 224
Quoted 4 lines
command-list.txt +1
-0+gitdetached-head guide gitdiffcore guide giteveryday guide gitfaq guideThis seems to be manually aligned with SP, so compensate the addition of "-" between detached and head by removing one SP before guide on the same line.
Will do.
PATCH v3 1/1 doc: checkout: rewrite detached HEAD state explanation
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
The current explanation has the following issues:
- Says detached HEAD state is useful but doesn't explain why
- Takes many paragraphs before explaining what detached HEAD state is
- It's common for users to accidentally end up in detached HEAD state, but it doesn't explain why that might happen
- One of the UI improvements in git switch is to make it harder to detach accidentally, but that isn't advertised.
See 7968bef06b (switch: only allow explicit detached HEAD, 2019-03-29)
- Too many confusing diagrams
Write a new explanation addressing these issues, and put it in a standalone guide so that we can easily reference it from advice ("see git help detached-head").
The result is a shorter guide that covers more material.
The framing that "Git considers commits that aren't on a branch/other reference to be garbage" is taken from Steve Klabnik's tutorial
https://steveklabnik.github.io/jujutsu-tutorial/branching-merging-and-conflicts/anonymous-branches.html.
It's funny and it's consistent with the way Git uses the term "garbage collection".
---
doc: checkout: rewrite detached HEAD state explanation
This is a pretty quick rewrite where we didn't get any user feedback. If we really want to make sure it's clear to users as possible, we should IMO do a second stage later where we ask users which parts are unclear.
Changes in v2:
* Make the meson.build and Makefile changes (thanks to Kristoffer)
* Rename to gitdata-model (thanks to Kristoffer)
* Mention commits will be deleted after 90 days to make it seem less scary (thanks to Kristoffer)
* Add an "easily" qualifier to "it lets you look at an old version of your code", to avoid implying that this is the only way (thanks to Junio)
* Mention that Git will warn you when switching branches if you're leaving commits behind (thanks to Junio)
* Remove "unintentionally" (thanks to Junio)
* Mention git help datamodel (thanks to Junio)
Changes in v3:
I went through the style comments from v1.
content changes:
* Change "90 days" to "30 days" (thanks to Junio)
* Say that HEAD is where Git stores your "current branch or commit" to make the first sentence read better (thanks to Junio)
* Mention git switch --detach a little earlier (thanks to Kristoffer)
* Replace "the only problem" with "it's important to know that" (thanks to Junio)
formatting changes etc:
* Replace help detachedhead with help detached-head (thanks to Junio)
* Fix spacing in command-list.txt (thanks to Junio)
* Get Marie's signoff (thanks to Junio)
non-changes: Left these phrases alone because I don't think the proposed changes would make it more clear.
* "3 main ways you can end up in detached HEAD state"
* "to look at an old version of your code"
* "avoid accidentally ending up"
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2250%2Fjvns%2Fdetached-head-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2250/jvns/detached-head-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/2250
Range-diff vs v2:
1: 83139be46f ! 1: 0ab8814664 doc: checkout: rewrite detached HEAD state explanation
@@ Commit message
Write a new explanation addressing these issues, and put it in a standalone guide so that we can easily reference it from advice
- ("see git help detachedhead").
+ ("see git help detached-head").
The result is a shorter guide that covers more material.
The framing that "Git considers commits that aren't on a branch/other
@@ Commit message
"garbage collection".
+ Signed-off-by: Marie Claire LeBlanc Flanagan <[email protected]>
## Documentation/Makefile ##
@@ Documentation/Makefile: MAN7_TXT += gitcore-tutorial.adoc
## Documentation/detached-head.adoc (new) ##
@@
-+HEAD is where Git stores your current branch. HEAD can either be:
++HEAD is where Git stores your current branch or commit. HEAD can either be:
+
+1. A branch, which is your current branch.
+2. A commit ID, when you don't have a current branch.
@@ Documentation/detached-head.adoc (new)
+For example, it lets you easily look at an old version of your code +(with git checkout COMMIT_ID or git switch --detach COMMIT_ID).
+
-+The only problem is that if you create new commits while in detached -+HEAD state, those commits won't be on a branch. This makes those new -+commits much harder to find later. Also, Git considers commits that -+aren't on any branch (or a tag or other reference) to be garbage. ++But it's important to know that if you create new commits while in ++detached HEAD state, those commits won't be on a branch. This makes ++those new commits much harder to find later. Also, Git considers commits ++that aren't on any branch (or a tag or other reference) to be garbage.
+Git will eventually permanently delete those "garbage" commits during
-+garbage collection. Those commits will be deleted after 90 days by ++garbage collection. Those commits will be deleted after 30 days by
+default, see linkgit:git-gc[1] for more.
+
+There are 3 main ways you can end up in detached HEAD state:
@@ advice.c: void detach_advice(const char *new_name)
"\n"
" git switch -\n"
"\n"
-+ "Run git help detachedhead to learn more.\n"
++ "Run git help detached-head to learn more.\n"
"Turn off this advice by setting config variable advice.detachedHead to false\n\n");
fprintf(stderr, fmt, new_name);
@@ command-list.txt: gitcore-tutorial guide
gitcredentials guide
gitcvs-migration guide
gitdatamodel guide
-+gitdetached-head guide
++gitdetached-head guide
gitdiffcore guide
giteveryday guide
gitfaq guide
Documentation/Makefile | 1 + Documentation/detached-head.adoc | 57 ++++++++++++ Documentation/git-checkout.adoc | 129 +--------------------------- Documentation/gitdetached-head.adoc | 14 +++ Documentation/meson.build | 1 + advice.c | 1 + command-list.txt | 1 + 7 files changed, 76 insertions(+), 128 deletions(-) create mode 100644 Documentation/detached-head.adoc create mode 100644 Documentation/gitdetached-head.adoc
Documentation/Makefile +1 -0
@@ -54,6 +54,7 @@ MAN7_TXT += gitcore-tutorial.adoc MAN7_TXT += gitcredentials.adoc MAN7_TXT += gitcvs-migration.adoc MAN7_TXT += gitdatamodel.adoc +MAN7_TXT += gitdetached-head.adoc MAN7_TXT += gitdiffcore.adoc MAN7_TXT += giteveryday.adoc MAN7_TXT += gitfaq.adoc
Documentation/detached-head.adoc new file +57 -0
57 lines not on this page · raw message
Documentation/git-checkout.adoc +1 -128
136 lines not on this page · raw message
Documentation/gitdetached-head.adoc new file +14 -0
@@ -0,0 +1,14 @@ +gitdetached-head(7) +=================== + +NAME +---- +gitdetached-head - How detached HEAD state works + +DESCRIPTION +----------- +include::detached-head.adoc[] + +GIT +--- +Part of the linkgit:git[1] suite
Documentation/meson.build +1 -0
@@ -197,6 +197,7 @@ manpages = { 'gitcredentials.adoc' : 7, 'gitcvs-migration.adoc' : 7, 'gitdatamodel.adoc' : 7, + 'gitdetached-head.adoc' : 7, 'gitdiffcore.adoc' : 7, 'giteveryday.adoc' : 7, 'gitfaq.adoc' : 7,
advice.c +1 -0
@@ -291,6 +291,7 @@ void detach_advice(const char *new_name)"\n" " git switch -\n" "\n" +"Run `git help detached-head` to learn more.\n" "Turn off this advice by setting config variable advice.detachedHead to false\n\n");fprintf (stderr, fmt, new_name);
command-list.txt +1 -0
@@ -218,6 +218,7 @@ gitcore-tutorial guide gitcredentials guide gitcvs-migration guide gitdatamodel guide +gitdetached-head guide gitdiffcore guide giteveryday guide gitfaq guide
base-commit: 5a7d1e8045ce66c908f62598e26cbb8df7b39a90
Signature · 1 line
gitgitgadget
Quoted 2 lines · Julia Evans via GitGitGadget
non-changes: Left these phrases alone because I don't think the proposed changes would make it more clear.
Those who contributed their time to review this document did so believing they were suggesting improvements. Simply dismissing their feedback as "style" in 'v2' without explaining what you disliked about their suggestions is unhelpful. It is hard to know what to make of a dismissal that lacks any supporting reasoning, other than "I don't think".
Documentation/detached-head.adoc line 5
Quoted 11 lines
Documentation/detached-head.adoc new file +5
-0@@ -0,0 +1,57 @@ +`HEAD` is where Git stores your current branch or commit. `HEAD` can either be: + +1. A branch, which is your current branch. +2. A commit ID, when you don't have a current branch. + This is called "detached HEAD state".
Differences between v1 and v3 did not make much improvement in this area, though. The phrase "branch or commit" highlights the distinction, but it fails to clarify what is common to both, which is equally important.
Perhaps restarting from something along this line
HEAD records the state from which your current changes started. This can be a branch (the "current branch"), or it be a commit, (in which case HEAD is "detached").
and polishing further may take us to a better end state. An important distinction that is not captured in the above (or your version) that we may want to cover is that when you are on a branch, your changes will grow that branch, and when you are not on a branch, your changes will not affect any branch and stay temporary.
Documentation/detached-head.adoc line 9
Quoted 3 lines
Documentation/detached-head.adoc new file +3
-0+It can sometimes be useful for `HEAD` to be a commit ID. +For example, it lets you easily look at an old version of your code +(with `git checkout COMMIT_ID` or `git switch --detach COMMIT_ID`).
We should use a verb stronger than "look at" to emphasize the primary advantage of having the entire state visible in the working tree. If a user merely wants to read or inspect a single historical file, they can do so easily without moving their HEAD by running 'git show COMMIT_ID:path/to/file'. Checking out a commit allows something much more powerful. It restores your entire working directory to that exact state.
In the detached HEAD state, you can safely build, run, and experiment with any historical version of your codebase, without having to worry about clobbering your branches, and you do not have to clutter your repository with temporary branches.
I said "safely build, run" because you had "old version of your CODE" in the paragraph, but if you can give examples outside the programming area, that would be even better. E.g.,
- Writers may able to rebuild and locally preview a complete historical version of a book or documentation site to see how cross-references and formatting rendered at that time.
- Game Designers may open an entire historical scene in an editor (like Unity or Blender) where assets, textures, and coordinates must all exist in a precise, interconnected state to load correctly.
- Data Scientists may execute and reproduce a specific historical data pipeline or model run using the exact combination of scripts and datasets that existed on that day.
Documentation/detached-head.adoc line 28
Quoted 10 lines
Documentation/detached-head.adoc new file +10
-0+There are 3 main ways you can end up in detached HEAD state: + +1. `git checkout COMMIT_ID`, where `COMMIT_ID` is a commit ID +2. `git checkout v1.3`, where v1.3 is a tag name +3. `git checkout origin/main`, where `origin/main` is + a remote-tracking branch + +Checking out a tag puts you in detached HEAD state because `HEAD` can +only be a branch or a commit, not a tag or any other reference. +So `git checkout TAG` will set HEAD to the commit for that tag.
A more standard phrase for "the commit for that tag" is "the tagged commit".
Because we will recommend "switch" to be a way to require to be more explicit when users mean to go into the detached HEAD state soon below, I think we would want to move the "checkout <COMMIT>" and "switch --detach <COMMIT>" description to here from the earlier "sometimes useful" paragraph, to complement the above list of ways to detach your HEAD.
Documentation/detached-head.adoc line 54
Quoted 13 lines
Documentation/detached-head.adoc new file +13
-0+If you switch branches after making commits in detached HEAD state, Git +will warn you that you might be about to "lose" those commits and print +out the commit ID. You can also always find those commits later using +linkgit:git-reflog[1]. + +Here's what that warning looks like: + +------------------------- +Warning: you are leaving 1 commit behind, not connected to +any of your branches: + + 48c09f6 3 +-------------------------
Your readers can guess that the 7 digit hex may probably be the commit object name you are about to lose, but you should use a bit more realistic descriptive title, not "3", to avoid confusion. I know many users do not write a good log message, but even a single word "bugfix" is better than "3" ;-)
Quoted 11 lines · Junio C Hamano
Quoted 2 lines · Julia Evans via GitGitGadget
non-changes: Left these phrases alone because I don't think the proposed changes would make it more clear.
Those who contributed their time to review this document did so believing they were suggesting improvements. Simply dismissing their feedback as "style" in 'v2' without explaining what you disliked about their suggestions is unhelpful. It is hard to know what to make of a dismissal that lacks any supporting reasoning, other than "I don't think".
My job to is write clear technical explanations and a big part of what I do is to try to reconcile the point of view of experts (who understand how the software works) and users (who know which parts are confusing). I think we've talked about this "curse of knowledge" issue before.
I'm always happy to have a detailed discussion when it comes to accuracy, and I'm extremely grateful for the time everyone puts in when it comes to pointing out accuracy issues, and when figuring out when it's appropriate to occasionally tell a "white lie" :)
The reason I was a little brief is that these in depth discussions about how to explain a concept as clearly as possible to users are not effective if there are no users involved in the process. It takes a lot of time without making substantial improvements.
There are some more ideas on this site about having a "user-centric" mindset, like using learner personas. Happy to talk about that if you think it would be helpful. Sometimes tone can get lost here so let me know if it would be helpful to have a video call!
https://www.writethedocs.org/blog/newsletter-june-2025/#help-contributors-think-like-users
Quoted 23 lines
Documentation/detached-head.adoc line 5
Quoted 11 lines
Documentation/detached-head.adoc new file +5
-0@@ -0,0 +1,57 @@ +`HEAD` is where Git stores your current branch or commit. `HEAD` can either be: + +1. A branch, which is your current branch. +2. A commit ID, when you don't have a current branch. + This is called "detached HEAD state".Differences between v1 and v3 did not make much improvement in this area, though. The phrase "branch or commit" highlights the distinction, but it fails to clarify what is common to both, which is equally important.
Perhaps restarting from something along this line
HEAD records the state from which your current changes started. This can be a branch (the "current branch"), or it be a commit, (in which case HEAD is "detached").
Quoted 5 lines
and polishing further may take us to a better end state. An important distinction that is not captured in the above (or your version) that we may want to cover is that when you are on a branch, your changes will grow that branch, and when you are not on a branch, your changes will not affect any branch and stay temporary.
This is a case where if we really want to make sure it's clear, we need to go get feedback from users. There's likely a better way to explain it but I don't think that this conversation will result in an improvement. Really doing a good job of explaining HEAD is a pretty big project.
It's not clear to me if you think the current wording is unusable or if you just think it could be better.
Quoted 11 lines
Documentation/detached-head.adoc line 9
Quoted 3 lines
Documentation/detached-head.adoc new file +3
-0+It can sometimes be useful for `HEAD` to be a commit ID. +For example, it lets you easily look at an old version of your code +(with `git checkout COMMIT_ID` or `git switch --detach COMMIT_ID`).We should use a verb stronger than "look at" to emphasize the primary advantage of having the entire state visible in the working tree. If a user merely wants to read or inspect a single historical file, they can do so easily without moving their HEAD by running 'git show COMMIT_ID:path/to/file'. Checking out a commit allows something much more powerful. It restores your entire working directory to that exact state.
Changed this to "check out an old version of your project".
Quoted 13 lines
In the detached HEAD state, you can safely build, run, and experiment with any historical version of your codebase, without having to worry about clobbering your branches, and you do not have to clutter your repository with temporary branches.
I said "safely build, run" because you had "old version of your CODE" in the paragraph, but if you can give examples outside the programming area, that would be even better. E.g.,
- Writers may able to rebuild and locally preview a complete historical version of a book or documentation site to see how cross-references and formatting rendered at that time.
Quoted 8 lines
- Game Designers may open an entire historical scene in an editor (like Unity or Blender) where assets, textures, and coordinates must all exist in a precise, interconnected state to load correctly.
- Data Scientists may execute and reproduce a specific historical data pipeline or model run using the exact combination of scripts and datasets that existed on that day.
I like these examples, added a shorter version of a couple of them. Also replaced "code" with "project" to make it more general.
Quoted 14 lines
Documentation/detached-head.adoc line 28
Quoted 11 lines
Documentation/detached-head.adoc new file +10
-0+There are 3 main ways you can end up in detached HEAD state: + +1. `git checkout COMMIT_ID`, where `COMMIT_ID` is a commit ID +2. `git checkout v1.3`, where v1.3 is a tag name +3. `git checkout origin/main`, where `origin/main` is + a remote-tracking branch + +Checking out a tag puts you in detached HEAD state because `HEAD` can +only be a branch or a commit, not a tag or any other reference. +So `git checkout TAG` will set HEAD to the commit for that tag.A more standard phrase for "the commit for that tag" is "the tagged commit".
Will do.
Quoted 6 lines
Because we will recommend "switch" to be a way to require to be more explicit when users mean to go into the detached HEAD state soon below, I think we would want to move the "checkout <COMMIT>" and "switch --detach <COMMIT>" description to here from the earlier "sometimes useful" paragraph, to complement the above list of ways to detach your HEAD.
Agreed there's some duplication here we can fix, will do.
Quoted 11 lines
Quoted 11 lines
Documentation/detached-head.adoc new file +11
-0+If you switch branches after making commits in detached HEAD state, Git +will warn you that you might be about to "lose" those commits and print +out the commit ID. You can also always find those commits later using +linkgit:git-reflog[1]. + +Here's what that warning looks like: + +------------------------- +Warning: you are leaving 1 commit behind, not connected to +any of your branches: +
Quoted 8 lines
Documentation/detached-head.adoc line 54
Quoted 2 lines
Documentation/detached-head.adoc new file +2
-0+ 48c09f6 3 +-------------------------Your readers can guess that the 7 digit hex may probably be the commit object name you are about to lose, but you should use a bit more realistic descriptive title, not "3", to avoid confusion. I know many users do not write a good log message, but even a single word "bugfix" is better than "3" ;-)
Oops, I meant to fix that before, thanks.
Quoted 7 lines · Julia Evans
This is a case where if we really want to make sure it's clear, we need to go get feedback from users. There's likely a better way to explain it but I don't think that this conversation will result in an improvement. Really doing a good job of explaining HEAD is a pretty big project.
It's not clear to me if you think the current wording is unusable or if you just think it could be better.
Then let me make it clear.
I do not know if your version is unusable or good enough, but if you are going to take one version to guinea-pig readers to test and polish starting from that version, I think what I gave you would give us a better starting point.
Otherwise I would not be suggesting replacements (this applies to all other points in the message you are responding to).
Thanks.
Quoted 10 lines · Junio C Hamano
Quoted 7 lines · Julia Evans
This is a case where if we really want to make sure it's clear, we need to go get feedback from users. There's likely a better way to explain it but I don't think that this conversation will result in an improvement. Really doing a good job of explaining HEAD is a pretty big project.
It's not clear to me if you think the current wording is unusable or if you just think it could be better.
Quoted 6 lines
Then let me make it clear.
I do not know if your version is unusable or good enough, but if you are going to take one version to guinea-pig readers to test and polish starting from that version, I think what I gave you would give us a better starting point.
I'm not planning to test this version on readers right now, no.
Here's what I wrote in the first email in this thread:
Often when rewriting these explanations I go through a process where I ask users' feedback on the old explanation. Here I didn't do that basically because that process takes a long time and I'm working on a bunch of other time consuming docs projects so I did a quick rewrite based on my previous experience explaining detached HEAD state to folks.
I thought this could be a nice quick docs win on a topic which many users find quite confusing. If the changes here are too controversial I can drop it for now.
PATCH v4 1/1 doc: checkout: rewrite detached HEAD state explanation
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
The current explanation has the following issues:
- Says detached HEAD state is useful but doesn't explain why
- Takes many paragraphs before explaining what detached HEAD state is
- It's common for users to accidentally end up in detached HEAD state, but it doesn't explain why that might happen
- One of the UI improvements in git switch is to make it harder to detach accidentally, but that isn't advertised.
See 7968bef06b (switch: only allow explicit detached HEAD, 2019-03-29)
- Too many confusing diagrams
Write a new explanation addressing these issues, and put it in a standalone guide so that we can easily reference it from advice ("see git help detached-head").
The result is a shorter guide that covers more material.
The framing that "Git considers commits that aren't on a branch/other reference to be garbage" is taken from Steve Klabnik's tutorial
https://steveklabnik.github.io/jujutsu-tutorial/branching-merging-and-conflicts/anonymous-branches.html.
It's funny and it's consistent with the way Git uses the term "garbage collection".
---
doc: checkout: rewrite detached HEAD state explanation
This is a pretty quick rewrite where we didn't get any user feedback. If we really want to make sure it's clear to users as possible, we should IMO do a second stage later where we ask users which parts are unclear.
Changes in v2:
* Make the meson.build and Makefile changes (thanks to Kristoffer)
* Rename to gitdata-model (thanks to Kristoffer)
* Mention commits will be deleted after 90 days to make it seem less scary (thanks to Kristoffer)
* Add an "easily" qualifier to "it lets you look at an old version of your code", to avoid implying that this is the only way (thanks to Junio)
* Mention that Git will warn you when switching branches if you're leaving commits behind (thanks to Junio)
* Remove "unintentionally" (thanks to Junio)
* Mention git help datamodel (thanks to Junio)
Changes in v3:
I went through the style comments from v1.
content changes:
* Change "90 days" to "30 days" (thanks to Junio)
* Say that HEAD is where Git stores your "current branch or commit" to make the first sentence read better (thanks to Junio)
* Mention git switch --detach a little earlier (thanks to Kristoffer)
* Replace "the only problem" with "it's important to know that" (thanks to Junio)
formatting changes etc:
* Replace help detachedhead with help detached-head (thanks to Junio)
* Fix spacing in command-list.txt (thanks to Junio)
* Get Marie's signoff (thanks to Junio)
non-changes: Left these phrases alone because I don't think the proposed changes would make it more clear.
* "3 main ways you can end up in detached HEAD state"
* "to look at an old version of your code"
* "avoid accidentally ending up"
Changes in v4:
* Fix commit message in example: "fix bug", not "3" (thanks to Junio)
* "commit for that tag" -> "tagged commit" (thanks to Junio)
* Move "git checkout COMMIT_ID or git switch --detach COMMIT_ID" down to the "3 main ways" list to reduce duplication (thanks to Junio)
* Add some examples and be clearer about how detached HEAD state lets you check out an old version of the project. (thanks to Junio)
non-changes:
* It's probably possible to explain HEAD better. That seems like a big project to me since HEAD in Git is a very tricky topic. I think it would be better to address in a separate patch series to have more time to think it through. Or if we think it's not possible to merge this without explaining HEAD better then I guess it shouldn't be merged.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2250%2Fjvns%2Fdetached-head-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2250/jvns/detached-head-v4
Pull-Request: https://github.com/gitgitgadget/git/pull/2250
Range-diff vs v3:
1: 0ab8814664 ! 1: 88210ad52d doc: checkout: rewrite detached HEAD state explanation
@@ Documentation/detached-head.adoc (new)
+2. A commit ID, when you don't have a current branch.
+ This is called "detached HEAD state".
+
-+It can sometimes be useful for HEAD to be a commit ID.
-+For example, it lets you easily look at an old version of your code -+(with git checkout COMMIT_ID or git switch --detach COMMIT_ID). ++It can sometimes be useful for HEAD to be a commit ID, because ++it lets you easily check out an old version of your project. For ++example, a data scientist could use this to run an old version of a ++data pipeline or a programmer could use this to figure out when a bug ++was introduced.
+
+But it's important to know that if you create new commits while in +detached HEAD state, those commits won't be on a branch. This makes
@@ Documentation/detached-head.adoc (new)
+
+There are 3 main ways you can end up in detached HEAD state:
+
-+1. git checkout COMMIT_ID, where COMMIT_ID is a commit ID
++1. git checkout COMMIT_ID or git switch --detach COMMIT_ID,
++ where COMMIT_ID is a commit ID.
+2. git checkout v1.3, where v1.3 is a tag name
+3. git checkout origin/main, where origin/main is
+ a remote-tracking branch
+
+Checking out a tag puts you in detached HEAD state because HEAD can +only be a branch or a commit, not a tag or any other reference.
-+So git checkout TAG will set HEAD to the commit for that tag. ++So git checkout TAG will set HEAD to the tagged commit.
+
+The easiest way to avoid accidentally ending up in detached HEAD state +is to use linkgit:git-switch[1] instead of linkgit:git-checkout[1] to
@@ Documentation/detached-head.adoc (new)
+Warning: you are leaving 1 commit behind, not connected to
+any of your branches:
+
-+ 48c09f6 3
++ 48c09f6 fix bug
+-------------------------
+
+For a more in-depth explanation of how HEAD works in Git,
Documentation/Makefile | 1 + Documentation/detached-head.adoc | 60 +++++++++++++ Documentation/git-checkout.adoc | 129 +--------------------------- Documentation/gitdetached-head.adoc | 14 +++ Documentation/meson.build | 1 + advice.c | 1 + command-list.txt | 1 + 7 files changed, 79 insertions(+), 128 deletions(-) create mode 100644 Documentation/detached-head.adoc create mode 100644 Documentation/gitdetached-head.adoc
Documentation/Makefile +1 -0
@@ -54,6 +54,7 @@ MAN7_TXT += gitcore-tutorial.adoc MAN7_TXT += gitcredentials.adoc MAN7_TXT += gitcvs-migration.adoc MAN7_TXT += gitdatamodel.adoc +MAN7_TXT += gitdetached-head.adoc MAN7_TXT += gitdiffcore.adoc MAN7_TXT += giteveryday.adoc MAN7_TXT += gitfaq.adoc
Documentation/detached-head.adoc new file +60 -0
60 lines not on this page · raw message
Documentation/git-checkout.adoc +1 -128
136 lines not on this page · raw message
Documentation/gitdetached-head.adoc new file +14 -0
@@ -0,0 +1,14 @@ +gitdetached-head(7) +=================== + +NAME +---- +gitdetached-head - How detached HEAD state works + +DESCRIPTION +----------- +include::detached-head.adoc[] + +GIT +--- +Part of the linkgit:git[1] suite
Documentation/meson.build +1 -0
@@ -197,6 +197,7 @@ manpages = { 'gitcredentials.adoc' : 7, 'gitcvs-migration.adoc' : 7, 'gitdatamodel.adoc' : 7, + 'gitdetached-head.adoc' : 7, 'gitdiffcore.adoc' : 7, 'giteveryday.adoc' : 7, 'gitfaq.adoc' : 7,
advice.c +1 -0
@@ -291,6 +291,7 @@ void detach_advice(const char *new_name)"\n" " git switch -\n" "\n" +"Run `git help detached-head` to learn more.\n" "Turn off this advice by setting config variable advice.detachedHead to false\n\n");fprintf (stderr, fmt, new_name);
command-list.txt +1 -0
@@ -218,6 +218,7 @@ gitcore-tutorial guide gitcredentials guide gitcvs-migration guide gitdatamodel guide +gitdetached-head guide gitdiffcore guide giteveryday guide gitfaq guide
base-commit: 5a7d1e8045ce66c908f62598e26cbb8df7b39a90
Signature · 1 line
gitgitgadget
Quoted 1 line · Julia Evans
I'm not planning to test this version on readers right now, no.
That is fine. But eventually we will reach the point where we have something we think is good enough to show to test readers, no? And I thought you were asking for help to improve the draft to reach that stage by sending the patch.
Quoted 11 lines
Here's what I wrote in the first email in this thread:
Often when rewriting these explanations I go through a process where I ask users' feedback on the old explanation. Here I didn't do that basically because that process takes a long time and I'm working on a bunch of other time consuming docs projects so I did a quick rewrite based on my previous experience explaining detached HEAD state to folks.
I thought this could be a nice quick docs win on a topic which many users find quite confusing. If the changes here are too controversial I can drop it for now.
After a long process, you may forget which suggestions you chose not to adopt by the time you are ready to show the draft to your test readers, and those who spent their brain cycles reviewing it might not notice that their input has been forgotten, either. I was worried about that kind of waste.
Thanks.
Quoted 3 lines · Julia Evans via GitGitGadget
This is a pretty quick rewrite where we didn't get any user feedback. If we really want to make sure it's clear to users as possible, we should IMO do a second stage later where we ask users which parts are unclear.
OK.
Quoted 6 lines
* It's probably possible to explain HEAD better. That seems like a big project to me since HEAD in Git is a very tricky topic. I think it would be better to address in a separate patch series to have more time to think it through. Or if we think it's not possible to merge this without explaining HEAD better then I guess it shouldn't be merged.
I do not understand why you need to draw a "take it or leave it" with this topic here. If you feel that the explanation of HEAD is iffy, you know what we have here will not be the final version, and you think we lack the capacity to reach the best possible description with the usual review exchange, then I do not see why you have to insist keeping what you initially have written. You can replace it with anything that is better than your initial version and then still record that we will further polish it later in the proposed log message and we will be in a better place, no?
Just to leave a record, so that we have better chance remembering the suggested improved text, here are what I think the first two paragraphs should be replaced with.
HEAD records the state from which your current changes started. This can be a branch (the "current branch"), or it be a commit, (in which case HEAD is "detached").
In the detached HEAD state, you can safely build, run, and experiment with any historical version of your codebase, without having to worry about clobbering your branches, and you do not have to clutter your repository with temporary branches.
Having said all that, the changes between v3 and v4 look OK to me, so let me update the previous copy I have with this version.
Quoted 7 lines · Julia Evans via GitGitGadget
advice.c | 1 +...
advice.c +0
-0
advice.c void detach_advice(const char *new_name) · line 297
Quoted 7 lines
advice.c +1
-0@@ -291,6 +291,7 @@ void detach_advice(const char *new_name)"\n" " git switch -\n" "\n" +"Run `git help detached-head` to learn more.\n" "Turn off this advice by setting config variable advice.detachedHead to false\n\n");fprintf (stderr, fmt, new_name);
This breaks t2020 without an accompanying change.
You can squash in the attached patch to unbreak the test.
Since nobody's terminal talks markdown or asciidoc, let's use the vanilla single quote instead of backquote while we are at it.
advice.c | 2 +- t/t2020-checkout-detach.sh | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-)
advice.c +1 -1
@@ -291,7 +291,7 @@ void detach_advice(const char *new_name)"\n" " git switch -\n" "\n" -"Run `git help detached-head` to learn more.\n" +"Run 'git help detached-head' to learn more.\n" "Turn off this advice by setting config variable advice.detachedHead to false\n\n");fprintf (stderr, fmt, new_name);
t/t2020-checkout-detach.sh +2 -0
@@ -228,6 +228,7 @@ test_expect_success 'describe_detached_head prints no SHA-1 ellipsis when not as git switch - + Run ${SQ}git help detached-head${SQ} to learn more. Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at \$commit three
@@ -310,6 +311,7 @@ test_expect_success 'describe_detached_head does print SHA-1 ellipsis when asked git switch - + Run ${SQ}git help detached-head${SQ} to learn more. Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at \$commit... three
Quoted 16 lines · Junio C Hamano
Documentation/detached-head.adoc line 5
Quoted 11 lines · Julia Evans via GitGitGadget
Documentation/detached-head.adoc new file +5
-0@@ -0,0 +1,43 @@ +`HEAD` is where Git stores your current branch. `HEAD` can either be: + +1. A branch, which is your current branch. +2. A commit ID, when you don't have a current branch. + This is called "detached HEAD state".HEAD is branch which can either be a branch or something else?
Quoted 4 lines
HEAD records the state from which your current changes started. This can be a branch (the "current branch"), or it may not be associated with any concrete branch (in which case HEAD is "detached").
You asked for a more detailed explanation for why I don't think this is clearer, so here's my best attempt.
It's important to use the same words that users might themselves use to describe a concept, for example, "means", "is", "points at", "is a reference to", etc.
In March 2024 I asked experienced Git users to explain their impressions of what HEAD means, and I got a lot of really great replies. I've included a bunch of them at the end of this email. I think it's a really great example of how there are a lot of "technically wrong but useful" ideas about how things in Git work. When I think about how to explain HEAD, it's in the context of that research I did around March 2024.
Your suggestion ("HEAD records the state from which your current changes started." uses pretty different language ("records") from the language users are using in the quotes below. I think it would be great if we could make a correct statement that builds on the ideas that users already have about HEAD, using the kind of language that they themselves would use to describe the ideas.
Let me know if this is a helpful way for you to bring some user perspectives into the conversation. Like I said earlier I don't really think it's possible to discuss how to explain HEAD in a vacuum so maybe these quotes will help!
Also if you could give me any ideas for how to reply in a "shorter" way than "I don't think this is clearer" let me know, I can't bring you quotes from user research to justify every single wording choice :)
- "HEAD is a mysterious thing I never need to know about unless something has g-one wrong, eg. merge conflicts."
-"the HEAD Commit in my Clone of our Repo is the Commit at the top of: git log"
- "Other than seeing "detached head" sometimes and panicking, I don't really know what Head is. And I used git quite a bit over the years 😅"
- "HEAD points at the latest commit of the branch you're viewing. Except when it doesn’t. There's attached and detached head situations and that's where it gets somewhat confusing."
- "It is a… thing… which “points at”… the newest (?) commit that “”I”” am ¿on?"
- "it's a pointer to the latest commit on the currently checked out branch"
- "HEAD means (a pointer to) the (commit hash of the) checked-out branch"
- "HEAD is the reference to the current commit that's checked out."
- "The commit which will be the parent of the next commit you create, at least using "git commit" command."
- "unless I am taking special pains to deliberately edit history, HEAD will
(1) become the first parent of whichever commit I write next AND (2) names the branch where that commit will be appended".
- "it's where you "currently are" on a branch (or maybe in the whole repo? not sure on head vs HEAD)"
- "the most recent commit on the branch you're working on"
- "Insertion point for new commits."
- "HEAD is a "commit-like"? that refers to the commit? that was used? to populate the working directory?"
- "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"
- "HEAD is a symbolic reference to another reference ... I don't have a mental model for what happens if HEAD points at a tag ref"
- "my impression is that it's the commit I'm currently looking at. It's attached if that commit is the tip of a branch (means I can make new commits), and it's detached when that is not the case."
- "it's a file that contains the currently checked-out commit id or branch name?"
- "Sometimes I think I kinda understand. Then I remember the existence of the phrase “detached HEAD”."
- "HEAD is what is going to be the parent of your next commit"
- "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. ... But if you're in a branch and not on the latest commit, HEAD still points at the latest commit."
- "HEAD is shorthand for "most recent commit on current branch"."
- "it means "the commit I have checked out at this very moment"."
- "I am quite unconfident as I only ever see it mentioned when running 'git reset'. From that context, something like "the most recent 'saved' state of the repo before you made any 'unsaved' modifications""
- "A pointer to the *latest* commit (not necessarily "current" commit) in whatever I'm working on. ... the latest commit" is whatever is conceptually "at the end" of the branch's timeline."
- "HEAD is used as a pointer to the current commit, while it is (usually) pointer to the current branch, which head (lowercase) points to the current commit - one layer of indirection."
- "I think of it as pointing to the next place where a commit would appear if I made one"
- "HEAD is a reference to a commit, either directly or indirectly. A direct commit is just in detached state, where HEAD is looking at the commit itself. An indirect reference would be the case you’ve shown above, where HEAD is a reference to a reference."
- "Its like... the thing at the end of the branch, right? Like... the current commit."
- "I think in practice it is the last ref checked out. Sometimes it is the SHA of the revision (detached head), sometimes it is a ref (branch or tag)."
- "HEAD means the head of a specific branch, which seems to be the default branch in github?"
- "the git command that involves HEAD which I use most often is git push origin HEAD ... I'd definitely struggle to articulate why this works the way that it does"
Quoted 3 lines · Julia Evans
Let me know if this is a helpful way for you to bring some user perspectives into the conversation. Like I said earlier I don't really think it's possible to discuss how to explain HEAD in a vacuum so maybe these quotes will help!
It surely is more helpful than "I think it is not better" that is not backed by anything.
Quoted 3 lines
Also if you could give me any ideas for how to reply in a "shorter" way than "I don't think this is clearer" let me know, I can't bring you quotes from user research to justify every single wording choice :)
IOW, "Trust me" ;-)
It is often good enough among those who have worked together for some time, and you certainly do qualify.
Quoted 2 lines
- "HEAD is a mysterious thing I never need to know about unless something has g-one wrong, eg. merge conflicts."
Somebody may have said so, but how does bringing it (together with many other examples) up in _this_ discussion help us find a better way to explain it to users?
Somebody is clueless about HEAD and does not feel the need to understand it until they really need to. This fact alone, that they can get going with such a sketchy understanding and make use of Git sufficiently well may be a great thing by itself. It may support an argument that we do not really have to explain what HEAD is to our readers. Is that the argument you are making?
I won't comment on each and every one of them, but is your point that many potential readers do not understand HEAD and doing fine?
Of course there are a handful of examples that they do get it, like this one.
Quoted 4 lines
- "HEAD is a reference to a commit, either directly or indirectly. A direct commit is just in detached state, where HEAD is looking at the commit itself. An indirect reference would be the case you’ve shown above, where HEAD is a reference to a reference."
But what did you want to illustrate again? I am little bit fuzzy on what you wanted to achieve by dumping these at me.
Thanks.
Quoted 12 lines · Junio C Hamano
Quoted 3 lines · Julia Evans
Let me know if this is a helpful way for you to bring some user perspectives into the conversation. Like I said earlier I don't really think it's possible to discuss how to explain HEAD in a vacuum so maybe these quotes will help!
It surely is more helpful than "I think it is not better" that is not backed by anything.
Quoted 8 lines
Quoted 3 lines
Also if you could give me any ideas for how to reply in a "shorter" way than "I don't think this is clearer" let me know, I can't bring you quotes from user research to justify every single wording choice :)
IOW, "Trust me" ;-)
It is often good enough among those who have worked together for some time, and you certainly do qualify.
That’s good to hear!
Quoted 14 lines
Quoted 2 lines
- "HEAD is a mysterious thing I never need to know about unless something has g-one wrong, eg. merge conflicts."
Somebody may have said so, but how does bringing it (together with many other examples) up in _this_ discussion help us find a better way to explain it to users?
Somebody is clueless about HEAD and does not feel the need to understand it until they really need to. This fact alone, that they can get going with such a sketchy understanding and make use of Git sufficiently well may be a great thing by itself. It may support an argument that we do not really have to explain what HEAD is to our readers. Is that the argument you are making?
Quoted 2 lines
I won't comment on each and every one of them, but is your point that many potential readers do not understand HEAD and doing fine?
I do think that’s true yes.
Quoted 10 lines
Of course there are a handful of examples that they do get it, like this one.
Quoted 4 lines
- "HEAD is a reference to a commit, either directly or indirectly. A direct commit is just in detached state, where HEAD is looking at the commit itself. An indirect reference would be the case you’ve shown above, where HEAD is a reference to a reference."
But what did you want to illustrate again? I am little bit fuzzy on what you wanted to achieve by dumping these at me.
Mostly to give an idea of the kind of language users are using when talking about Git, to explain why saying “records” isn’t appropriate and why more generally it might not be possible for me to accept your suggested wordings for how to explain things verbatim. For example elsewhere in this thread you suggested another wording and seemed to find it hard to understand why I wouldn't replace what Marie and I had written with your suggested “better” wording.
Also I have the impression that our assumptions about what Git users know and what users need are quite different, and I thought it might help illustrate why I might have a different point of view.
I agree these kinds of comments can be a little unsettling to read when some of them are “wrong”. I believe that these comments are from folks who are quite a bit more knowledgeable than the average Git user.
It’s my job to sort through them and figure out how to write the docs with them in mind and I’m definitely not asking you to do that :) I do need some trust though.
Quoted 3 lines
I agree these kinds of comments can be a little unsettling to read when some of them are “wrong”. I believe that these comments are from folks who are quite a bit more knowledgeable than the average Git user.
I forgot the mandatory XKCD here :) https://xkcd.com/2501/
Hi all,
I've read through this thread a few times, and I'm still interested in seeing the detached HEAD manual land. It seems like the following need to happen?
1. We are waiting on a reroll from Julia with the SQUASH??? commit or something like it applied
(https://lore.kernel.org/git/[email protected]/)
2. The discussion about how to describe HEAD needs resolved.
Quoted 5 lines · Junio C Hamano
Just to leave a record, so that we have better chance remembering the suggested improved text, here are what I think the first two paragraphs should be replaced with.
Quoted 8 lines
HEAD records the state from which your current changes started. This can be a branch (the "current branch"), or it be a commit, (in which case HEAD is "detached").
In the detached HEAD state, you can safely build, run, and experiment with any historical version of your codebase, without having to worry about clobbering your branches, and you do not have to clutter your repository with temporary branches.
Here's what Junio suggested^, and here's what v4 has
+HEAD is where Git stores your current branch or commit. HEAD can either be:
+
+1. A branch, which is your current branch.
+2. A commit ID, when you don't have a current branch.
+ This is called "detached HEAD state".
+
+It can sometimes be useful for HEAD to be a commit ID, because +it lets you easily check out an old version of your project. For +example, a data scientist could use this to run an old version of a +data pipeline or a programmer could use this to figure out when a bug +was introduced.
I do not personally think it's worth focusing on "the state from which your current changes started" (even leaving aside the "what if I have no changes?" moment), in part because I don't think that's how most users conceive of HEAD. Other than that detail, I think the first paragraphs of each option coincide.
There are some quotes which use the "it's the parent of the next commit" mental model, though, so we could include a comment on that? It might be distracting, and could make its way into some kind of admonition/aside if need be?
The second paragraphs differ a bit, with Junio's containing some bits about clobbering extant branches and not needing temporary branches. I think we could work something in there, like
It can sometimes be useful for HEAD to be a commit ID, because it lets you easily check out an old version of your project. For example, a data scientist could use this to run an old version of a data pipeline or a programmer could use this to figure out when a bug was introduced. By detaching HEAD, you don't need to worry about clobbering an existing branch or creating a temporary branch.
? I suppose we could also be more explicit ("build, run, and experiment"), if we wanted, but this is a good example to start from.
Quoted 2 lines
Having said all that, the changes between v3 and v4 look OK to me, so let me update the previous copy I have with this version.
Otherwise, we're approaching a finish here?
Signature · 1 line
D. Ben Knoble
Quoted 12 lines · D. Ben Knoble
+
HEADis where Git stores your current branch or commit.HEADcan either be:Documentation/detached-head.adoc new file +10
-0+ +1. A branch, which is your current branch. +2. A commit ID, when you don't have a current branch. + This is called "detached HEAD state". + +It can sometimes be useful for `HEAD` to be a commit ID, because +it lets you easily check out an old version of your project. For +example, a data scientist could use this to run an old version of a +data pipeline or a programmer could use this to figure out when a bug +was introduced.
Quoted 2 lines
There are some quotes which use the "it's the parent of the next commit" mental model, though, so we could include a comment on that?
"From which your current changes started" is exactly that. HEAD is where you started from (and can come back to, if you get lost after botching your working tree state). Your next commit is built on top of it, and then that new commit becomes your current commit.
This is why it is useful for users to realize that HEAD is simply where you started from, regardless of where you are going.
Quoted 10 lines
The second paragraphs differ a bit, with Junio's containing some bits about clobbering extant branches and not needing temporary branches. I think we could work something in there, like
...
this to figure out when a bug was introduced. By detachingHEAD, you don't need to worry about clobbering an existing branch or creating a temporary branch.? I suppose we could also be more explicit ("build, run, and experiment"), if we wanted, but this is a good example to start from.
I assume you mean the last two lines? I do appreciate that addition.
However, we should avoid saying "useful for HEAD to be a commit ID". Being a commit ID is not the notable characteristic of a detached HEAD; the fact that it directly refers to a commit is what gives us these useful features. Recording a hexadecimal commit object name (instead of a refname of a branch) is a mere implementation detail of that direct reference.
Since Julia's introductory paragraph already established the term "detached HEAD" very well, there is no need to resort to a roundabout phrasing like "useful for HEAD to be a commit ID". I suggest rewriting the beginning of that paragraph to start with:
It can be useful for the HEAD to be directly refering to a commit (instead of indirectly referring to a commit by naming the current branch).
This introduces the remainder of her paragraph much better, and makes your addition about not needing to worry about clobbering existing branches or consuming temporary refs easier to understand.
Quoted 1 line
Otherwise, we're approaching a finish here?
I hope so. The document overall is moving in the right direction, and I just want to see these minor technical descriptions improved.
Quoted 22 lines · Junio C Hamano
Quoted 12 lines · D. Ben Knoble
+
HEADis where Git stores your current branch or commit.HEADcan either be:Documentation/detached-head.adoc new file +10
-0+ +1. A branch, which is your current branch. +2. A commit ID, when you don't have a current branch. + This is called "detached HEAD state". + +It can sometimes be useful for `HEAD` to be a commit ID, because +it lets you easily check out an old version of your project. For +example, a data scientist could use this to run an old version of a +data pipeline or a programmer could use this to figure out when a bug +was introduced.Quoted 2 lines
There are some quotes which use the "it's the parent of the next commit" mental model, though, so we could include a comment on that?
"From which your current changes started" is exactly that. HEAD is where you started from (and can come back to, if you get lost after botching your working tree state). Your next commit is built on top of it, and then that new commit becomes your current commit.
Quoted 2 lines
This is why it is useful for users to realize that HEAD is simply where you started from, regardless of where you are going.
I think it's reasonable to try to explain that in both cases there's something in common.
Here's an idea for how to do that:
In Git, you can always use HEAD to refer to the current commit. But HEAD isn't just your current commit: it's also where Git stores the name of your current branch. HEAD can either be:
1. A branch, which is your current branch.
The current commit is the latest commit on that branch.
2. A commit ID, when you don't have a current branch. This is called "detached HEAD state".
It can sometimes be useful for HEAD to be a commit ID, because...
Quoted 11 lines
Quoted 10 lines
The second paragraphs differ a bit, with Junio's containing some bits about clobbering extant branches and not needing temporary branches. I think we could work something in there, like
...
this to figure out when a bug was introduced. By detachingHEAD, you don't need to worry about clobbering an existing branch or creating a temporary branch.? I suppose we could also be more explicit ("build, run, and experiment"), if we wanted, but this is a good example to start from.
Quoted 8 lines
I assume you mean the last two lines? I do appreciate that addition.
However, we should avoid saying "useful for HEAD to be a commit ID". Being a commit ID is not the notable characteristic of a detached HEAD; the fact that it directly refers to a commit is what gives us these useful features. Recording a hexadecimal commit object name (instead of a refname of a branch) is a mere implementation detail of that direct reference.
Saying "it's a commit ID" is a simple way to say that it directly refers to a commit in a small number of words. I'm not sure what your goal is here, do you think that statement is somehow misleading to users?
Quoted 8 lines · Julia Evans
Quoted 7 lines · Junio C Hamano
Documentation/detached-head.adoc line 5
Quoted 5 lines · D. Ben Knoble
+
HEADis where Git stores your current branch or commit.HEADcan either be:Documentation/detached-head.adoc new file +4
-0+ +1. A branch, which is your current branch. +2. A commit ID, when you don't have a current branch. + This is called "detached HEAD state".
Quoted 4 lines
...
Saying "it's a commit ID" is a simple way to say that it directly refers to a commit in a small number of words. I'm not sure what your goal is here, do you think that statement is somehow misleading to users?
Yes, I find it highly misleading, and otherwise I wouldn't be discussing this patch.
I think the part I find it problematic the most in
HEAD is a branch vs HEAD is a commit ID
is that HEAD *IS NOT* either of these things. HEAD may record one of these kinds of things but it never is a branch or an commit object name.
And HEAD records one of these kinds of things to either directly or indirectly refer to a commit that is currently checked out.
That is why I want to see the first description of the above to serve as a solid base to convey these points, with later descriptions we build on top:
* HEAD can record either (1) a branch, or (2) a commit object name.
* The purpose of HEAD doing so is to refer to a commit that is currently checked out, either directly or indirectly.
* The latter (i.e., the direct reference) may be unfamiliar to users. It is called "detached HEAD" state.
* The commit referred to by the HEAD will become the parent of the commit you create. When your HEAD records a branch, its tip is advanced. Otherwise no branch is affected. Either case, HEAD now refers to the commit you newly created.
And I find that saying "HEAD is a branch" or "HEAD is a commit" is misleading and does not help that goal.
HTH.
I'm going to reply to this email a bit out of order because I want to say this is a great list first:
Quoted 10 lines
That is why I want to see the first description of the above to serve as a solid base to convey these points, with later descriptions we build on top:
*
HEADcan record either (1) a branch, or (2) a commit object name.* The purpose of HEAD doing so is to refer to a commit that is currently checked out, either directly or indirectly.
Quoted 7 lines
* The latter (i.e., the direct reference) may be unfamiliar to users. It is called "detached HEAD" state.
* The commit referred to by the HEAD will become the parent of the commit you create. When your HEAD records a branch, its tip is advanced. Otherwise no branch is affected. Either case, HEAD now refers to the commit you newly created.
I'm not sure if we need to communicate the last point here, but definitely the goal is to communicate the first 3 points.
Quoted 2 lines
... And HEAD records one of these kinds of things to either directly or indirectly refer to a commit that is currently checked out.
now back to the beginning:
Quoted 7 lines
And I find that saying "HEAD is a branch" or "HEAD is a commit" is misleading and does not help that goal.
Quoted 3 lines
Saying "it's a commit ID" is a simple way to say that it directly refers to a commit in a small number of words. I'm not sure what your goal is here, do you think that statement is somehow misleading to users?
Quoted 7 lines
Yes, I find it highly misleading, and otherwise I wouldn't be discussing this patch.
I think the part I find it problematic the most in
HEAD is a branch vs HEAD is a commit ID
is that HEAD *IS NOT* either of these things.
The all caps "IS NOT" doesn't help me understand why it's misleading but it does tell me you feel strongly about this so I assume it's important :) It might help to give an example of something a user might believe about HEAD that is not true as a result of reading this.
I'll try a different suggestion and see if that helps though.
Often I approach this issue by talking about Git's implementation directly, like ".git/HEAD is a file that can contain either a branch name or commit ID". Usually I think it's not good to talk about the implementation that way, but I think HEAD might be an exception because in practice I've found that users find the explanation of the implementation helpful.
Here's a version which handles the issue by talking about .git/HEAD.
In Git, you can always use HEAD to refer to the commit you have checked out. But HEAD is also where Git stores the name of your current branch. Internally, .git/HEAD is a file that contains either:
1. A branch name, which is your current branch.
The commit you have checked out is the latest commit on that branch.
2. A commit ID, when you don't have a current branch.
This is called "detached HEAD state".
It can sometimes be useful for HEAD to refer to a commit directly because it lets you easily check out an old version of your project.
...
But talking about the implementation in this way isn't a good idea (even though it might have been okay 10 years ago) because immediately as soon as we make the reftable backend the default, users will try to look at .git/HEAD and it won't be there, which will cause confusion.
We could talk about git symbolic-ref HEAD but that introduces a whole other can of worms of "what is a symbolic ref" and I don't know is helpful.
Quoted 3 lines
HEAD may record one
of these kinds of things but it never is a branch or an commit object name.
What does the verb "record" mean to you? I've seen you and other folks in the Git project use a lot but I've never totally understood what it's intended to mean. I haven't seen it used in this way outside of the Git project.
Like I said before in this thread, it's important to use verbs that users themselves might use to describe a concept (references, points to, etc). Does "records" mean the same thing as "references" or "points to" from your perspective? My guess is no, because "references" and "points to" can also refer to indirect references, and I think "records" may mean something more specific. Maybe it means something like "there's an abstract key-value store in Git where the key is 'HEAD' and the value is a branch name or commit ID"?
"Records" is not a good word to use to communicate with users about this topic because the meaning of the verb won't be understood.