Home DevOps Git Detached HEAD: Recover Without Losing Commits
Beginner 5 min · September 23, 2026

Git Detached HEAD: Recover Without Losing Commits

Stay calm and create a branch where you are.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Drawn from code that ran under real load.

Follow
Production
production tested
September 23, 2026
last updated
1,905
articles · all by Naren
Before you start⏱ 10 min
  • Git installed with basic checkout and commit comfort
  • A clone where you can detach HEAD without risk (any test repo)
  • A shell prompt or alias setup you can tweak to show Git state
 ● Production Incident 🔎 Debug Guide
Quick Answer
  • Detached HEAD means HEAD points at a raw commit instead of a branch, usually after checking out a tag, an old commit, or a remote ref
  • Anything you commit while detached is real but branchless, so create a branch with git branch -c rescue to keep it safe
  • Return to safety with git checkout - or git switch -; your work stays on the rescue branch you just made
  • If you already left without saving, run git reflog, find your commit hash, and branch from it before it gets pruned
✦ Definition~90s read
What is Git Detached HEAD Recovery?

Detached HEAD is a positioning state, not an error: the HEAD reference contains a raw commit hash instead of a path like refs/heads/main. Normally HEAD is symbolic — it names a branch, and the branch names the commit, so committing advances the branch pointer automatically.

Picture branches as labeled bookmarks and commits as pages in a notebook.

Checkout of anything that isn't a local branch tip (a tag, a historical hash, a remote-tracking branch, a stash commit, a PR ref) can't advance any branch, so Git aims HEAD at the commit directly and reports detachment. Commits you make there are structurally complete — message, tree, parents, hash — but parented onto a chain no ref advertises.

Reachability is the underlying mechanism. Git keeps an object alive while some ref (branch, tag, reflog entry, stash) can reach it, and garbage-collects the rest. Your detached commits survive through reflog entries recording each HEAD position, which is why git reflog resurrects them and why expiry windows matter.

Branching the hash adds a durable ref, promoting the commits from reflog-protected to permanently reachable.

What detached HEAD is NOT: it isn't corruption, it isn't a broken clone, and it doesn't mean your branches lost commits — other branches are untouched. It also isn't a permission problem or a lock. Think of it as standing on a page with the bookmark in your pocket: reading is fine, writing needs the bookmark placed first.

The whole topic reduces to pointer literacy — knowing what HEAD names right now — plus the two reflexes of branching before leaving and checking the reflog after.

Plain-English First

Picture branches as labeled bookmarks and commits as pages in a notebook. Normally your bookmark sits on the latest page and moves forward as you write. Checking out an old commit pulls the bookmark out and drops you on that page directly — you're reading fine, but new pages you write have no bookmark holding them. They exist, yet nothing points at them. The fix is embarrassingly simple: stick a new bookmark where you stand before you walk away.

You checked out a tag to reproduce a bug, or an old commit to run a bisect, and now your prompt says 'detached HEAD' in alarming colors. Then you fixed the bug, committed twice, and switched back to main — and your commits seem to have vanished into thin air. Take a breath: they're almost certainly still in your repo, reachable through the reflog, waiting for a branch to adopt them.

Detached HEAD just means HEAD points directly at a commit hash instead of at a branch reference. Git enters this state whenever you check out something that isn't a local branch tip: a tag, a historical commit, a remote-tracking ref, or a pull-request ref. In this state everything works — you can edit, stage, and commit — but new commits grow on an unnamed nub that no branch follows. Leave that spot without naming it and the commits look lost.

Recovery is two moves: name your current spot with a branch before you leave, and use checkout - to hop back. If you already left, the reflog recorded every HEAD position, so you can find the hash and branch from it. This guide covers why detachment happens, how to save work in place, how to resurrect abandoned commits, and how to work on old code without getting stranded again.

Why Git Detaches Your HEAD in the First Place

HEAD is a pointer that normally aims at a branch reference like refs/heads/main, and the branch reference aims at a commit. Checking out a branch moves HEAD to the reference, so new commits advance the branch automatically. But tags, raw hashes, and remote-tracking refs aren't branches — there's no reference to advance. When you check one out, Git points HEAD directly at the commit and warns you the HEAD is detached. It's not an error state; it's Git being honest that no branch will follow your next commit.

The usual triggers are all legitimate workflows: git checkout v1.2.3 to reproduce a customer bug on the released code, git checkout 9f3ac2e during a bisect, git checkout origin/main to peek at the server's state, or fetching a pull-request ref to test someone's changes. Each puts you on a specific commit with no branch semantics. Problems start only when you commit in this state and then move away, because the new commits have no name pointing at them.

Notice that Git tells you plainly every time: 'You are in detached HEAD state' plus instructions for keeping your work. The state also shows in git status and in most shell prompts. Detachment is only dangerous when combined with inattention — engineers who read the banner branch in time, and engineers who ignore it learn about the reflog the hard way.

📊 Production Insight
Bisect sessions are the top detachment factory: git bisect checks out raw commits a dozen times per run, and engineers who 'just fix it while I'm here' commit onto a bisect checkout. One team now runs bisect with a pre-agreed rule — no commits during bisect, notes in a scratch file — after losing a fix into a checkout they'd already moved past.
🎯 Key Takeaway
Detachment happens whenever you check out a non-branch: tag, hash, or remote ref. It's a normal inspection state. It only eats work when you commit branchless and leave without naming the spot.

Save Work In Place: Branch Before You Bounce

If you're detached right now and your commits matter, do nothing that moves HEAD. Don't check out main, don't bisect further, don't fetch-and-reset. Run git branch -c rescue-name while standing on your newest commit. That single command creates a branch reference pointing exactly where HEAD points, adopting your whole anonymous chain instantly. Your commits are now ordinary branch commits with a name, a log, and a pushable ref.

From there, return to familiar ground with git checkout - (the dash means 'wherever I was before') or git switch -. Your rescue branch stays behind, intact, holding every commit. Verify with git log --oneline rescue-name, then treat it like any feature branch: rebase it onto main, review it, merge it. Nothing about its detached origin makes it second-class once it has a name.

Prefer git switch -c rescue-name when you also want to move onto the branch immediately — it creates the branch and checks it out in one motion, carrying uncommitted changes along. The habit to drill is ordering: name first, move second. Every recovery story that ends well follows that order, and every story that ends in the reflog skipped it. Once safe, decide calmly whether to merge, rebase, or cherry-pick the rescued commits onto your main line.

save-detached-work.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Confirm you're detached and see what you'd be leaving behind
git status | head -3
git log --oneline -5

# Name your current spot WITHOUT moving (safe, instant)
git branch -c rescue-nil-guard

# Verify the branch holds your commits, then hop back
# ('-' means 'wherever I was before this checkout')
git log --oneline rescue-nil-guard
git checkout -

# Alternative: create the branch AND move onto it in one step
# (carries uncommitted working-tree changes along)
git switch -c rescue-nil-guard

# Treat it like any feature branch from here
# (rebase onto main, review, merge)
git rebase main
git push -u origin rescue-nil-guard
📊 Production Insight
The 9 PM deploy incident in this article resolved in minutes once someone ran branch -c, because the commits were sitting exactly where the engineer left them. The 41-minute delay was pure diagnosis time — nobody recognized the pattern. Teams that rehearse 'detached? branch first' turn this into a 30-second fix.
🎯 Key Takeaway
Name first, move second. git branch -c rescue adopts your commits instantly, checkout - hops back, and switch -c does both at once.

Resurrect Abandoned Commits With the Reflog

The reflog is Git's flight recorder: every position HEAD ever occupied, with the command that moved it and a timestamp. Commits you left behind detached still exist as objects, and the reflog entry pointing at them keeps them alive. Run git reflog and scan for your commit messages or the 'checkout: moving from abc1234 to main' line — the hash on the left side of that move is where your work sits.

Once you have the hash, resurrect with git branch rescue-name <hash>. Your commits reappear as an ordinary branch, ready for log, rebase, and push. If you remember nothing but the message fragment, git log --all --grep='nil guard' --oneline can find commits across every ref including the reflog-adjacent ones. For truly desperate cases, git fsck --lost-found recovers dangling commits even after reflog expiry, though you'll be identifying them by content rather than message.

Act with reasonable speed but not panic. Default reflog expiry keeps unreachable entries for 30 to 90 days, so a same-day rescue is trivially safe. Still, don't let 'Git keeps everything' become an excuse to postpone: aggressive gc configs, deleted clones, and fresh checkouts can narrow your options. Branch the moment you find the hash, then breathe.

reflog-rescue.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Flight recorder: every HEAD position with command + timestamp
git reflog | head -20

# Narrow to your lost commits by message fragment
# (works across all refs, not just the current branch)
git log --all --oneline --grep='nil guard' | head -10

# The 'moving from <hash>' line names where you stood: branch it
# (replace abc1234 with the hash from your reflog)
git branch rescue-nil-guard abc1234
git log --oneline rescue-nil-guard

# Last resort after reflog expiry: recover dangling commits by content
git fsck --lost-found
git log --oneline --no-walk --all | head -20

# Never lose them again: push the rescued branch to the server now
git push -u origin rescue-nil-guard
💡Reflog first, panic never
Left a detached checkout without branching? Your commits are still objects in the repo. git reflog names the hash you abandoned, and git branch rescue <hash> adopts it back. Same-day rescues succeed essentially always.
📊 Production Insight
One engineer's laptop died two days after abandoning detached commits, and the replacement clone had no reflog — the objects never left the old disk. Recovery meant mounting the dead SSD. The lesson stuck: push rescue branches to the server the moment they're created, because the reflog only exists in the clone where it happened.
🎯 Key Takeaway
git reflog finds the abandoned hash, git branch rescue <hash> adopts it, and fsck --lost-found covers even expired entries. Push the rescue branch immediately.

Checkout Minus: the Fast Way Back to Safety

The dash argument is Git's 'take me back' shortcut: git checkout - (and git switch -) returns to the branch or commit you occupied before the current one. After you've branched your detached work, one dash-hop puts you back on main with your files updated and your rescue branch safely stored. It's the same muscle memory as cd - in the shell, and it eliminates the 'wait, which branch was I on' guessing that causes second mistakes during recovery.

Combine it with verification and the loop closes cleanly: branch -c to save, checkout - to return, branch -vv to confirm both refs exist where you expect. If you hop back and your working tree looks wrong, don't compound it — git status tells you which branch you're on and whether stray changes followed you. Stash or commit them deliberately rather than dragging detached-state edits silently onto main.

Teach the dash to your whole team alongside the rescue habit. Recovery under deploy pressure goes wrong when engineers type branch names from memory at speed. checkout - needs no memory: it always means back, and back is almost always where you want to stand while deciding what to do with the rescued branch. After hopping back, glance at git branch -vv output to confirm both refs sit where you expect before running anything destructive.

hop-back-safely.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Full save-and-return loop in three commands
git branch -c rescue-nil-guard
git checkout -
git branch -vv

# Modern equivalent with switch (same dash behavior)
# git switch -c rescue-nil-guard
# git switch -

# If stray edits followed you back, park them deliberately
# (don't let detached-state changes leak silently onto main)
git status --short
git stash push -m "detached-session leftovers"
git stash list
📊 Production Insight
During the 9 PM incident, the rescuing engineer typed the return branch from memory and landed on a stale release branch instead of main, costing 6 extra minutes of confusion. checkout - would have returned to the exact prior branch with zero recall. Under time pressure, shortcuts that need no memory beat ones that do.
🎯 Key Takeaway
checkout - always means 'where I just was'. Save with branch -c, return with the dash, verify with branch -vv, and stash any edits that followed you.

Work on Old Code Without Getting Stranded

Most detachment is avoidable with one habit: branch at checkout time. Instead of git checkout v2.14.0, run git checkout -b verify-bug v2.14.0. You land on the identical code, but on a real branch that follows your commits, pushes cleanly, and opens pull requests. Delete it when done. The cost is one flag; the benefit is never needing rescue in the first place.

For read-only missions, staying detached is genuinely fine — bisect runs, test archaeology, diffing two releases. The rule is intent: if there's any chance you'll commit, branch first. git worktree offers an even cleaner option for parallel old-code work: git worktree add ../hotfix-214 v2.14.0 gives the old code its own directory and branch while your main checkout stays put, eliminating the whole leave-and-return dance.

Remote-ref peeking deserves the same treatment. git checkout origin/main detaches by design, since the remote-tracking ref isn't yours to advance. If the peek turns into work, switch -c immediately. Engineers who treat every checkout-of-a-non-branch as 'branch or read-only, decide now' simply stop producing stranded commits. Add the rule to onboarding docs so new hires learn it before their first tag checkout, not after their first rescue.

branch-old-code.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Inspecting an old release? Land on a branch, not in the void
# (identical code, but commits get a name and a push path)
git checkout -b verify-bug v2.14.0

# Same for raw hashes and remote refs
# (never commit onto a bare hash checkout)
git checkout -b bisect-fix 9f3ac2e
git checkout -b peek-origin origin/main

# Cleanest parallel option: separate directory + branch, main checkout untouched
# (no leave-and-return dance at all)
git worktree add ../hotfix-214 v2.14.0
git worktree list

# Read-only missions need no branch: look, test, then hop back
# (bisect, blame, running old tests — just don't commit)
git checkout v2.13.0
git checkout -
📊 Production Insight
A support team that verifies every customer bug against the customer's exact tag switched to checkout -b verify-<ticket> <tag> as policy. Stranded-commit incidents dropped from roughly one a month to zero in half a year, and each verification branch doubles as an audit trail of what was tested against which release.
🎯 Key Takeaway
checkout -b <name> <tag-or-hash> lands on identical code with a real branch. Use worktrees for parallel old-code work and stay read-only when you stay detached.

Make Detachment Unmissable in Your Environment

Humans miss banner text under pressure, so make the state visually loud. Shell prompt plugins (starship, powerlevel10k, git-prompt) can render detached HEAD in red with the short hash, turning every terminal glance into a status check. The team in this article's incident added exactly that, and it has caught four near-misses since — engineers seeing red DETACHED before committing, branching first, and never entering recovery at all.

Pair the prompt with a pre-commit nudge for extra safety: a hook that warns when HEAD is detached still permits intentional commits but forces acknowledgment. Some teams go further and alias checkout of tags to auto-create branches, though explicit habits beat magic — an engineer who understands detachment handles novel cases, while an alias only handles the ones it was written for.

Document the two-command rescue in your runbook where on-call eyes can find it at night: branch -c to save, reflog to resurrect. Incidents compress working memory, and a runbook entry turns 'I vaguely remember a blog post' into copy-paste recovery. The goal isn't just surviving detachment; it's making the state so visible and the rescue so rehearsed that it stops costing you deploys.

detached-guardrails.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Show detached state loudly in every prompt (example: __git_ps1)
# (add to ~/.bashrc; shows red DETACHED plus short hash when applicable)
git config --global status.short true
PS1='[$(git branch --show-current 2>/dev/null || echo "DETACHED $(git rev-parse --short HEAD)")] \$ '

# Warn on every commit attempt while detached (permits, but forces awareness)
# (install as .git/hooks/pre-commit, chmod +x)
# if ! git symbolic-ref -q HEAD >/dev/null; then
#   echo "WARNING: committing in detached HEAD state." >&2
#   echo "Run: git switch -c rescue-name   (then commit there)" >&2
# fi

# One-line state check for runbooks and scripts
# (empty output from --show-current means detached)
git branch --show-current; git rev-parse --short HEAD; git status -sb | head -1
⚠ Prompts beat memory under pressure
Nobody reads checkout banners at 8:50 PM before a deploy. A red DETACHED prompt catches what tired eyes miss. Add the indicator once and it guards every future checkout.
📊 Production Insight
After the deploy scare, the team's red-prompt change paid off within three weeks when a new hire saw DETACHED, asked what it meant, and branched before committing. A five-minute environment tweak converted a future 40-minute incident into a 30-second question. That's the highest ROI change in this entire article.
🎯 Key Takeaway
Render detached state in red in every prompt, add a pre-commit warning hook, and put the two-command rescue in the on-call runbook.
● Production incidentPOST-MORTEMseverity: high

Two Hotfix Commits Vanished Before a 9 PM Deploy Freezing 14 Engineers

Symptom
At 8:19 PM, thirty minutes before a scheduled production deploy, an engineer announced the hotfix was ready but couldn't push it: git log on main didn't show either fix commit, and git status was clean. The deploy captain held the pipeline while 14 engineers watched the release channel. The two commits — a nil-guard and its regression test — existed nowhere any branch could reach, and the tag they'd been built on couldn't accept new work.
Assumption
The engineer assumed checking out the v2.14.0 tag put them on a branch that tracked the release, and that committing twice plus switching back to main would carry the work along. Nobody noticed the 'detached HEAD' banner in the checkout output because the tag name looked like a branch and the commit commands all succeeded normally.
Root cause
HEAD pointed at tag v2.14.0's commit directly, not at any branch, so the two fix commits grew on an anonymous chain with no ref pointing at them. Running git checkout main moved HEAD away, leaving both commits unreferenced except by reflog entries. The work was never in danger of instant deletion, but with no branch name the engineer had no path to push it, and the deploy had a hard 9 PM cutoff tied to a third-party maintenance window.
Fix
A second engineer ran git reflog, spotted the two 'commit: fix nil guard' entries with their hashes, and created git branch hotfix/nil-guard <hash> at the newer commit. They checked it out, rebased it onto main, pushed the branch, and fast-tracked review. CI went green in 11 minutes and the deploy launched at 8:52 PM, 8 minutes before the cutoff. The team then added a shell prompt plugin that turns red and says DETACHED so the state is unmissable.
Key lesson
  • Detached HEAD commits are real commits with no address. Name your spot with git branch -c before leaving it, and a scary state becomes a two-second save. Make 'branch before you bounce' a reflex for the whole team.
  • Checkout output deserves a glance, not a skim. Git announces detachment explicitly every time, but engineers trained to ignore command output walk past it. Read the first three lines of every checkout, especially when a tag or hash is involved.
  • A prompt that shows Git state turns invisible danger visible. The red DETACHED indicator added after this incident has since caught four near-misses before any commit was made. Environment design beats memory every time.
Production debug guideFive situations from best case to worst case, each with the exact commands that save your work and get you back on a branch.5 entries
Symptom · 01
You're detached right now with new commits you want to keep
Fix
Stay where you are and run git branch -c rescue-name to name your current spot, then git checkout - to return to your previous branch. Verify with git log --oneline rescue-name. Your commits now live on rescue-name and you can merge or rebase them normally. This is the entire fix when you catch it in time.
Symptom · 02
You're detached with uncommitted changes and afraid to switch
Fix
Don't switch yet. Either commit the changes where you stand (git stash works too), then branch with git branch -c rescue-name. Alternatively run git switch -c rescue-name, which creates the branch and moves you onto it in one step including your working tree. Confirm with git status that the tree followed you.
Symptom · 03
You already left the detached spot without creating a branch
Fix
Run git reflog and look for your 'commit:' lines or the 'checkout: moving from <hash> to main' entry that names the hash you left. Create a branch at that hash: git branch rescue-name <hash>. Then git log --oneline rescue-name to confirm your commits are there. Act promptly; reflog entries eventually expire.
Symptom · 04
You need to work on an old commit or tag deliberately
Fix
Don't sit detached. Create the branch first: git checkout -b investigation <tag-or-hash>. Now you're on a normal branch at the old code, free to commit, push, and open a PR. For read-only inspection (bisect, blame, running tests), staying detached is fine — just don't commit unless you've branched.
Symptom · 05
You can't tell whether you're detached or which branch you're on
Fix
Run git status (it says 'HEAD detached at <hash>' or 'Not currently on any branch'), git branch --show-current (empty means detached), and git log --oneline -3 to see where you stand. Knowing your exact state before running recovery commands prevents branching from the wrong spot.
Detached HEAD Situations — Confirm, Fix, Prevent
Root CauseHow to ConfirmFixPrevention
Checked out a tag or old commit, then committedgit status says 'HEAD detached at <hash>' with your commits in git loggit branch -c rescue to name the spot, then checkout - to returngit checkout -b name <tag> so old code always has a branch
Left the detached spot without branchinggit reflog shows 'checkout: moving from <hash> to main'git branch rescue <hash> from the reflog, verify with git logRule: name first with branch -c, move second, every time
Detached with uncommitted changes, afraid to movegit status shows modified files plus 'Not currently on any branch'git switch -c rescue to adopt spot plus tree, or stash then branchDecide branch-or-read-only before checking out a non-branch
Can't tell which state you're ingit branch --show-current prints empty; git status names the hashEmpty output means detached; branch -c if you have work, checkout - if notInstall a prompt that renders DETACHED in red with the hash
Need parallel work on old codeMain checkout is mid-task but a release tag needs a fixgit worktree add ../dir <tag> for a separate directory plus branchDefault to worktrees for hotfixes so main stays untouched
⚙ Quick Reference
5 commands from this guide
FileCommand / CodePurpose
save-detached-work.shgit status | head -3Save Work In Place
reflog-rescue.shgit reflog | head -20Resurrect Abandoned Commits With the Reflog
hop-back-safely.shgit branch -c rescue-nil-guardCheckout Minus
branch-old-code.shgit checkout -b verify-bug v2.14.0Work on Old Code Without Getting Stranded
detached-guardrails.shgit config --global status.short trueMake Detachment Unmissable in Your Environment

Key takeaways

1
Detached HEAD means HEAD aims at a commit, not a branch. Inspection is safe; branchless commits need naming.
2
git branch -c rescue saves work in place. Name first, move second, every single time.
3
git checkout - returns to your previous branch with no name recall under pressure.
4
git reflog resurrects abandoned commits by hash. git fsck covers even expired entries.
5
Branch at checkout (checkout -b name tag) or use worktrees so old-code work starts safe.
6
A red DETACHED prompt plus a runbook entry turns future incidents into non-events.

Common mistakes to avoid

6 patterns
×

Switching back to main before naming the detached spot

Symptom
Your commits disappear from every branch log, git status is clean, and panic sets in because the work looks deleted.
Fix
Branch before you bounce: git branch -c rescue while still detached. If you already left, recover the hash from git reflog and branch from it.
×

Committing a 'quick fix' onto a bisect checkout

Symptom
The bisect ends, HEAD moves on, and your fix rides an anonymous commit chain nobody can find without digging through reflog entries.
Fix
Keep bisect sessions read-only; jot fixes in a scratch file. When a fix can't wait, git switch -c fix-name first, then commit.
×

Assuming a tag checkout behaves like a branch

Symptom
Commits succeed normally so everything feels safe, until switching away reveals no branch ever tracked them and pushing has no upstream to target.
Fix
Treat tags as read-only labels. For tag-based work always git checkout -b name <tag> so commits land on a real branch.
×

Deleting the clone or resetting before checking the reflog

Symptom
Re-cloning 'to start fresh' destroys the only reflog containing your abandoned commits, turning a trivial rescue into forensic recovery.
Fix
Never delete or re-clone until git reflog and git fsck --lost-found come up empty. The evidence lives in that clone.
×

Force-pushing the rescue branch over main to 'put the fix back'

Symptom
The rescued commits land but main's newer history gets overwritten, trading a personal recovery problem for a team-wide outage.
Fix
Rebase the rescue branch onto main and merge normally. Rescue restores your work; only review and merge publish it.
×

Ignoring the detached HEAD banner in checkout output

Symptom
Git announced the state explicitly, but skimming past it means the first sign of trouble is missing commits twenty minutes later.
Fix
Read checkout output's first lines always, and install a red DETACHED prompt so the state stays visible for the whole session.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What does detached HEAD mean, and how do you get into that state?
Q02JUNIOR
You committed twice while detached and haven't moved. How do you keep th...
Q03SENIOR
You already switched back to main without branching. The commits look go...
Q04SENIOR
How do you deliberately work on a release tag without risking stranded c...
Q05SENIOR
The reflog expired and the clone is gone, but the commits were pushed to...
Q01 of 05JUNIOR

What does detached HEAD mean, and how do you get into that state?

ANSWER
HEAD points directly at a commit instead of a branch reference, usually after checking out a tag, a raw hash, or a remote-tracking ref. It's a normal inspection state: everything works, but new commits grow on an unnamed chain no branch follows. Save them with git branch -c name before moving away.
FAQ · 6 QUESTIONS

Frequently Asked Questions

01
Is detached HEAD dangerous? Did I break my repo?
02
Where did my detached commits go after I switched branches?
03
What's the difference between git checkout - and git checkout main?
04
Can I push while detached?
05
How long does the reflog keep my abandoned commits?
06
Does git bisect leave me detached? Should I worry?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Drawn from code that ran under real load.

Follow
Verified
production tested
September 23, 2026
last updated
1,905
articles · all by Naren
🔥

That's Git. Mark it forged?

5 min read · try the examples if you haven't

Previous
Git Failed to Push Some Refs Fix
49 / 51 · Git
Next
Git Unrelated Histories Merge Fix