Desk Clarity

Everyday document & browser help

Detached HEAD after checking out origin: preserve commits before switching

By ON Lab · Sources checked November 8, 2026

git checkout origin/topic checks out the commit recorded by a remote-tracking reference; it does not put you on a local branch named topic. If you have made commits while detached and want to keep them, create a new branch at the current commit before switching away: git switch -c rescue-work. To begin ordinary work from a remote branch, create a local tracking branch instead.

Detached HEAD is a repository state, not proof that Git failed or that a commit disappeared. The next action depends on whether you were only inspecting a snapshot or have work to retain. This guide uses a local bare repository and clone to verify both paths. It does not operate on your remote server.

Read the state before changing it

git status
git branch --show-current
git log -1 --oneline
git rev-parse HEAD

In our detached fixture, git branch --show-current produced no branch name, while git rev-parse HEAD still identified a valid commit. Record that full identifier if there is work you may want to retain.

The two names can initially point to the same commit but mean different things. A local branch is a movable name that advances when you commit on it. A remote-tracking name such as origin/topic is your local record of a fetched server branch. Checking out that recorded commit does not turn it into your own local working branch.

If you have committed work to keep, name it first

git switch -c rescue-work
git branch --show-current
git rev-parse HEAD
git log -2 --oneline

Choose an unused, descriptive name in place of rescue-work. Do not add origin/topic or another start point to this rescue command: the purpose here is to name the commit you are currently on. Confirm that the full commit identifier after creating the branch matches the one you recorded before it.

This is the step that preserves an existing detached commit under a branch name. Creating a new tracking branch from the remote's older tip is a different operation and can leave your new detached commit outside that new branch. It is easy to mix these two intentions when a tutorial jumps directly from “detached HEAD” to “create a tracking branch.”

If you have uncommitted changes, git status will identify them separately from the commit. Creating the branch at the current commit does not itself commit those edits. Review and save them through your normal workflow; do not treat a matching commit hash as proof that uncommitted files are included.

If you want normal work from the remote branch

When you have no detached work to retain, or have already named it, inspect the available local and remote-tracking branches:

git branch
git branch -r

If the intended local branch already exists, switch to that local name, for example git switch topic. If it does not exist and the intended remote-tracking reference is present, explicitly create a local tracking branch:

git switch -c topic --track origin/topic
git branch -vv
git rev-parse --abbrev-ref --symbolic-full-name '@{u}'

The placeholder names must match your repository. If topic already exists, do not force-reset it just to make the command succeed. Inspect its history and upstream first. If the remote-tracking branch is missing, confirm the remote and fetch status before inventing a name. This setup does not push your local branch or publish your rescued commit.

What we verified in a disposable repository

We created one commit on main and pushed it to a local bare remote. Checking out origin/main produced a detached state. We then changed a test file and made a second commit while detached. That new commit had a different full identifier from the original main tip.

Next, git switch -c rescue-work created a branch without changing the current commit identifier. We switched back to main and confirmed that it still pointed to the original commit, while rescue-work pointed to the new one. Both commits remained addressable. That comparison checks the actual outcome rather than merely accepting the branch-creation success message.

We also tried git switch origin/main. Our Git rejected it because it expected a local branch. Creating local-main explicitly with --track origin/main succeeded, and the upstream query returned origin/main. The rescue branch still identified the detached commit afterward. These are local command-line results, not a test of every graphical Git client.

If you already switched away

Do not assume an unnamed commit is already lost, and do not start with destructive cleanup. A recorded full commit identifier is useful evidence. Git's checkout documentation explains detached-commit recovery using the reflog when the identifier is no longer in the terminal output. Inspect the relevant reflog entry and its changes before creating a branch at it; do not choose a commit only because its timestamp looks plausible.

This guide's verified rescue sequence starts while still on the detached commit. It does not claim to have reconstructed a reader's repository after garbage collection or recovered deleted object data. If you cannot identify the right commit, retain the repository and exact command history for further investigation instead of running cleanup commands.

Choose the outcome, then verify it

A branch name is a way to retain and navigate a commit. It is not an automatic merge, remote publication or proof that your working directory is clean. Check those outcomes separately before continuing.

Sources