| `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. | |
| 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 30 days by | |
| default, see linkgit:git-gc[1] for more. | |
| There are 3 main ways you can end up in detached HEAD state: | |
| 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 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 | |
| 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 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 fix bug | |
| ------------------------- | |
| For a more in-depth explanation of how `HEAD` works in Git, | |
| see linkgit:gitdatamodel[7] (`git help datamodel`). |