Last modified: September 13, 2025

This article is written in: πŸ‡ΊπŸ‡Έ

Understanding HEAD

HEAD is Git’s pointer to the snapshot you’re currently working onβ€”the bookmark of your checkout. Most of the time, HEAD points to the tip of a branch (like master or main). When you commit, HEAD (and that branch) advance to the new commit.

Time →                                                     (commits left→right)

                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Merge ──────────────┐
main        ──●──┼──●───────────●───────────●───────●────────▢
               A1    A2         M1          A3     A4     (branch tip: main)
                 \               ^                   \
                  \              β”‚                    \
feature/login      β—β”€β”€β”€β—β”€β”€β”€β—β”€β”€β”€β”€β”€β”˜                     ●─────●──▢
                  F1   F2  F3                          M2    F4   (HEAD -> feature/login)

hotfix/urgent           β—β”€β”€β”€β”€β—β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       H1   H2

Tags/Remotes:
  (origin/main) at A3     (v1.2) tag at M1

Legend:
  ●   = commit node
  A*, F*, H* = commit short IDs (on main, feature/login, hotfix/urgent)
  M*  = merge commits
  HEAD -> <branch> means your working tree points to that branch’s tip

Detached HEAD

A detached HEAD is when HEAD points directly to a commit instead of to a branch tipβ€”usually after checking out a specific commit hash or a tag.

This is what it looks like when you check out a specific commit:

main        ──●──●──●──●──●──▢
               A1  A2  A3  A4

(HEAD) ----------------^
                     (checked out at commit A3, no branch name)

Here HEAD points to A3 itself, not a branch. New commits would form an orphaned line unless you first make a branch, e.g. git switch -c temp-work.

What Happens When You Commit on a Detached HEAD

If you commit (F) while HEAD is detached at commit C, history forks:

A <-- B <-- C (HEAD) <-- F
             \
              D <-- E (master)

Commit F is not on master. If you switch back to master, there’s no branch reference to F unless you merge, cherry-pick, or create a branch pointing to it. If left unattached, F can be garbage-collected once unreachable.

Detaching HEAD: Switching to a Specific Commit

You enter a detached HEAD state by checking out a commit hash or tag. For example:

git switch b4d373k8990g2b5de30a37bn843b2f51fks2b40

Or equivalently:

git checkout b4d373k8990g2b5de30a37bn843b2f51fks2b40

HEAD now points to that exact commit rather than a branch tip. Git will say:

Note: switching to 'b4d373k8990g2b5de30a37bn843b2f51fks2b40'.

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 switching back to a branch.

That’s your cue: commits made now live off to the side until you attach them to a branch (e.g., git switch -c keep-this).

Creating a Branch from a Detached HEAD

Sometimes you realize you’ve made valuable commits while detached and want to keep them. The safe fix is to create a branch at the commit you’re on and then switch to it.

git branch new_branch

Then switch to it:

git switch new_branch

Now new_branch contains all commits you made while HEAD was detached, and you’re no longer detachedβ€”HEAD points to the branch tip again. Your work is preserved and anchored to new_branch.

Before:
A <-- B <-- C (HEAD) <-- F

After creating and switching to new_branch:
A <-- B <-- C <-- F (new_branch, HEAD)

F is no longer β€œfloating”; it’s anchored to the new_branch branch.

Tip: You can do this in one step with git switch -c new_branch. Verify where you are with git status or git branch --show-current.

Preventing a Detached HEAD State

It’s cleaner to avoid a detached HEAD unless you’re only looking. If you intend to make changes, create a branch at that commit first so new work has a name and a home.

Example Scenario: You want to check out an older commit to debug or reproduce behavior.

I. Create a branch named old_version at that commit:

git branch old_version b4d373k8990g2b5de30a37bn843b2f51fks2b40

II. Switch to old_version:

git switch old_version

Now, any commits you make stay on old_versionβ€”no work drifts unreferenced.

Tip: One-step variant: git switch -c old_version b4d373k8990g2b5de30a37bn843b2f51fks2b40.

Switching Back to a Branch from a Detached HEAD

When you’re done exploring a detached commit, just jump back to a normal branch (like master):

git switch master

or

git checkout master

You’ll be right where master last pointed. If you made commits while detached and haven’t put them on a branch yet, do so before switchingβ€”or recover them later via git reflog and then create a branch to keep them.

Merging Changes from a Detached HEAD into a Branch

You’ve made useful commits while detached and want them on master. The trick is to merge the commit that contains your work (usually the latest one on that detached line) into master.

I. Switch to master (the branch you want to bring changes into):

git switch master

(Or git checkout master.) Tip: If your default branch is main, substitute accordingly.

II. Merge the detached commit (use the tip commit’s hash):

git merge b4d373c8990a2b5de30a37bf843b2f51f5c2b400

This creates a merge commit tying your detached line into master. You’re effectively stitching that β€œloose thread” back into the main history. If Git reports conflicts:

git status               # see which files need attention
# resolve conflicts in your editor
git add <file_with_conflicts>
git merge --continue     # or: git commit

Now your detached changes are part of master, recorded with a merge commit.

(master)                (HEAD detached)
   |                          |
   D <-- E                   C <-- F
    \                      /
     ------ Merge Commit --

Result: a single continuous history where F’s changes are integrated into master.

Notes

Table of Contents

    Understanding HEAD
    1. Detached HEAD
    2. What Happens When You Commit on a Detached HEAD
    3. Detaching HEAD: Switching to a Specific Commit
    4. Creating a Branch from a Detached HEAD
    5. Preventing a Detached HEAD State
    6. Switching Back to a Branch from a Detached HEAD
    7. Merging Changes from a Detached HEAD into a Branch