In Git, **HEAD** is a pointer that tells you which commit your working directory is currently based on. Normally, HEAD points to a branch name (like `main`), and that branch points to the latest commit. When you make new commits, the branch moves forward and HEAD follows along.

A **detached HEAD** means HEAD is pointing directly at a specific commit instead of a branch. You're looking at the repository at a particular point in time, but you're not "on" any branch. Git warns you about this because any new commits you make won't belong to a branch and could be lost.

```bash
$ git status
HEAD detached at 8fd3350
nothing to commit, working tree clean
```

## Common ways you end up in detached HEAD state

You won't usually end up here by accident during normal day-to-day work. These are the typical causes:

- **Checking out a specific commit:** `git checkout 8fd3350` puts you at that exact commit, detached from any branch.
- **Checking out a tag:** `git checkout v1.2.0` --- tags point to commits, not branches.
- **Interactive rebase conflicts:** during a rebase, Git temporarily detaches HEAD as it replays commits.
- **Checking out a remote branch directly:** `git checkout origin/main` detaches because `origin/main` is a remote tracking ref, not a local branch.

## What happens when you checkout a commit

When you run `git checkout` on a specific commit hash, Git tells you exactly what's going on:

```bash
$ git checkout 8fd3350cf6fba8bcd4abc7233d4ff6b81dd6ed3c
Note: checking out '8fd3350cf6fba8bcd4abc7233d4ff6b81dd6ed3c'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 8fd3350 Add the correct link to Brie
```

This is actually useful. Detached HEAD is a good way to inspect old code, test something against a previous version, or experiment without affecting any branch.

## Saving your work from detached HEAD

If you've made commits while in detached HEAD state, don't worry --- your work isn't lost yet. Create a new branch from where you are:

```bash
git checkout -b my-experiment
```

Or using the newer `git switch` command:

```bash
git switch -c my-experiment
```

This creates a branch pointing at your current commit, so all your work is safely on a named branch. You can then push it as usual:

```bash
git push --set-upstream origin my-experiment
```

## Returning to a normal branch

If you haven't made any changes you need to keep, simply switch back to a branch:

```bash
git checkout main
```

Or with `git switch`:

```bash
git switch main
```

You'll be back on the latest commit of `main` with HEAD properly attached.

If you *did* make commits in detached HEAD state but forgot to create a branch, you can still recover them. Git keeps unreferenced commits for a while (usually 30 days) before garbage collecting them. Use `git reflog` to find the commit hash, then create a branch from it:

```bash
git reflog
# Find the commit hash from the output
git branch recovered-work abc1234
```

For more on recovering lost work, see our guide on [recovering a deleted branch](/git/faqs/recover-deleted-branch-git).

## Related

- [`git checkout` command reference](/git/commands/git-checkout) --- switching branches and checking out commits
- [`git branch` command reference](/git/branching-and-merging) --- creating and managing branches
- [Branching and merging](/git/branching-and-merging) --- working with branches in Git
- [Recovering a deleted branch](/git/faqs/recover-deleted-branch-git) --- using reflog to find lost commits

---

[DeployHQ](https://www.deployhq.com) deploys from the branch you choose, so you never have to worry about detached HEAD state in your deployment pipeline. Connect your repository and [start deploying](https://www.deployhq.com/signup).
