Scenario
Section titled “Scenario”You checked out an older commit to reproduce a bug — a perfectly normal thing to do. While there,
you fixed it and committed. Then you switched back to main to carry on.
The fix is not on main. It is not on any branch. git log --all does not show it.
You committed on a detached HEAD, and Git told you so at the time. This lab is about noticing that message, and about what to do when you did not.
Objective
Section titled “Objective”Make a commit on a detached HEAD, lose it, and recover it — and read the warning Git prints so that next time the recovery happens before the commit is lost.
Prerequisites
Section titled “Prerequisites”- Git installed (
git --version) - Lab 01, or an understanding that a branch is a pointer
- HEAD explains what “detached” means; the lab shows it
Starting state
Section titled “Starting state”mkdir -p /tmp/lab-lost && cd /tmp/lab-lostgit init -q -b main .git config user.email "lab@example.com"git config user.name "Lab User"
echo "# Project" > README.mdgit add . && git commit -q -m "Initial commit"echo "v1" > app.txtgit add . && git commit -q -m "Add app"echo "v2" > app.txtgit add . && git commit -q -m "Update app to v2"
git log --onelineThree commits on main:
cb83610 Update app to v2e273666 Add appf5813f4 Initial commit-
Detach HEAD at the previous commit, as you would to inspect an older version:
Terminal window git switch --detach HEAD~1Git says
HEAD is now at e273666 Add app. Rungit statusand read the first line. -
Commit while detached. Pretend you found and fixed a bug here:
Terminal window echo "hotfix" > fix.txtgit add . && git commit -q -m "Emergency hotfix on detached HEAD"git log --onelineThe new commit is at the top. Its parent is
e273666, notmain’s tip. -
Switch back to
mainand read everything Git prints:Terminal window git switch mainDo not skip the output. Git is telling you exactly what is about to happen and how to prevent it.
-
Confirm the commit is gone from every branch:
Terminal window git log --oneline --allThree commits. The hotfix is not listed. Is it deleted?
-
Find it. Two tools will show it — try both:
Terminal window git refloggit fsck --lost-found -
Recover it by putting a branch on it. Use the SHA from either command:
Terminal window git branch hotfix <sha>git log --oneline --all
Validation
Section titled “Validation”After step 6, git log --oneline --all lists four commits and git branch shows hotfix. Run
git switch hotfix && ls — fix.txt is there.
Step 3. The warning begins Warning: you are leaving 1 commit behind. It names the commit
and prints the recovery command. Most people never read it because it appears at the moment they
have already decided to move on.
Step 5. The reflog records every movement of HEAD, including the commit you made while
detached and the switch away from it. git fsck --lost-found finds the same commit a different
way: by looking for objects nothing references.
Step 6. git branch <name> <sha> creates a branch without switching to it. git switch -c
would also work and switch as well.
Solution
Section titled “Solution”Step 3’s output, in full:
Warning: you are leaving 1 commit behind, not connected toany of your branches:
291d542 Emergency hotfix on detached HEAD
If you want to keep it by creating a new branch, this may be a good timeto do so with:
git branch <new-branch-name> 291d542
Switched to branch 'main'The reflog, after the switch:
cb83610 HEAD@{0}: checkout: moving from 291d542860f8df289c3475d4ec2722b0a439252c to main291d542 HEAD@{1}: commit: Emergency hotfix on detached HEADe273666 HEAD@{2}: checkout: moving from main to HEAD~1cb83610 HEAD@{3}: commit: Update app to v2e273666 HEAD@{4}: commit: Add appf5813f4 HEAD@{5}: commit (initial): Initial commitHEAD@{1} is the commit. Note that HEAD@{0} says “moving from 291d542…” — a raw SHA rather
than a branch name, because there was no branch.
git fsck --lost-found:
dangling commit 291d542860f8df289c3475d4ec2722b0a439252cRecovery:
git branch hotfix 291d542git log --oneline --all291d542 Emergency hotfix on detached HEADcb83610 Update app to v2e273666 Add appf5813f4 Initial commitYour SHAs will differ.
Explanation
Section titled “Explanation”Detached HEAD means HEAD points at a commit, not a branch. Normally HEAD contains
ref: refs/heads/main and committing moves main. When HEAD contains a raw commit ID, committing
moves HEAD itself — and nothing else. No branch advances.
Switching away leaves the commit with no pointer. It is not deleted; it is unreachable from any
ref. git log --all walks from refs, so it cannot see it. The reflog, which records HEAD’s
movements rather than walking the graph, still can.
Git warned you. The “leaving commits behind” message is printed precisely when a switch would strand commits. It includes the recovery command. Reading it turns a recovery into a non-event.
The safe habit: if you are going to commit while detached, create a branch first —
git switch -c fix-attempt — and the question never arises.
Troubleshooting
Section titled “Troubleshooting”git switch main printed no warning. You committed nothing while detached, so there was
nothing to leave behind. Repeat step 2.
The reflog does not show the commit. You may be reading a different repository’s reflog —
check pwd. The reflog is per-repository and per-clone.
git branch hotfix <sha> says “not a valid object name”. The SHA was mistyped. Copy it from the
reflog; the seven-character prefix is enough.
Clean up
Section titled “Clean up”cd /tmp && rm -rf lab-lostRelated lessons
Section titled “Related lessons”Next lab
Section titled “Next lab”Undo a bad merge — two different fixes for the same mistake, depending on whether anyone has seen it.