Git 顯示 detached HEAD,不是壞掉:先替實驗提交留一個分支 / Detached HEAD Is Not Broken: Name the Commit You Want to Keep

現象:看到 detached,不代表壞掉 / Detached does not mean broken

假設你為了查看舊版本,執行 git switch --detach HEAD~1,終端機卻跳出 detached HEAD。畫面裡的「detached」很像檔案壞了,其實 Git 只是告訴你:現在的 HEAD 沒有掛在任何分支名稱上。你仍能查看檔案、修改內容,甚至提交;真正要留意的是,新提交暫時沒有分支名稱替它保留位置。

Suppose you inspect an older revision with git switch --detach HEAD~1 and the terminal reports a detached HEAD. “Detached” sounds like something broke, but Git is only saying that HEAD is not attached to a branch name. You may still inspect files, edit, and commit. The part that needs attention is that a new commit is not yet retained by a branch name.

HEAD 與分支原本怎麼連 / How HEAD normally follows a branch

平常在 main 上工作時,HEAD 是符號參照,也就是它先指向 refs/heads/main,而 main 再指向某個提交。建立新提交後,Git 會把 main 移到新提交,HEAD 因為跟著 main,也間接移動。官方資料模型則把 detached HEAD 定義成另一種合法狀態:HEAD 直接保存提交 ID,沒有目前分支。[1][2]

While working on main, HEAD is normally a symbolic reference: it points to refs/heads/main, and main points to a commit. Creating a commit moves main to the new commit, so HEAD follows indirectly. Git’s official data model defines detached HEAD as another valid state: HEAD stores a commit ID directly, with no current branch. [1][2]

一般分支中 HEAD 透過 main 指向提交;detached HEAD 則直接指向提交,值得保留時要建立分支名稱 / On a branch HEAD reaches a commit through main; detached HEAD points directly to a commit, so create a branch name for work worth keeping
圖一|detached 不是資料損壞,而是少了分支這一層名稱;reflog 可協助復原,但不是遠端備份。原創示意圖,非產品或實測截圖。 / Figure 1 | Detached means the branch-name layer is absent, not that data is corrupt. Reflog can aid recovery but is not a remote backup. Original diagram, not a product or test screenshot.

這常發生在你切到標籤、提交雜湊,或明確使用 --detach 時。它適合唯讀檢查與可以丟棄的實驗,因為原本的 main 不會被移動。要注意,這不是「不能提交」:官方 checkout 文件示範,detached 狀態仍能一路建立新提交,只是最後一個提交起初只被 HEAD 指到。[1][3]

This commonly happens after switching to a tag, a commit hash, or using --detach explicitly. It is useful for read-only inspection and disposable experiments because the original main branch does not move. It does not mean “commits are forbidden”: the official checkout documentation shows that new commits can be created normally, but the last one is initially referenced only by HEAD. [1][3]

切走之前,先替提交留名字 / Name the commit before leaving

影響會在你切回分支時出現。HEAD 改回指向 main 後,剛才那條實驗提交可能沒有任何分支或標籤指著;Git 文件稱它之後可能被例行垃圾回收刪除。更精確地說,提交不是切換瞬間就消失,而是失去容易找到、長期保留的名稱,因此別把「暫時還找得到」誤認成已安全保存。[1]

The consequence appears when you switch back to a branch. After HEAD points to main again, the experimental line may have no branch or tag referring to it; Git’s documentation says routine garbage collection may eventually remove it. More precisely, the commit does not vanish at the moment of switching. It loses an easy, durable name, so “I can still find it for now” is not the same as “it is safely retained.” [1]

如果實驗值得留下,而且你還停在那個提交,最小動作是 git switch -c saved-experiment。這會在目前提交建立分支並切過去;之後的新提交就會推進這個分支。若只想加名稱但維持 detached,也可以用 git branch saved-experiment。先用 git status 或 git branch --show-current 看清狀態,再決定要保存或丟棄。[1][3]

If the experiment is worth keeping and you are still on that commit, the smallest action is git switch -c saved-experiment. This creates a branch at the current commit and switches to it; later commits will advance that branch. To add a name while remaining detached, use git branch saved-experiment. Check the state first with git status or git branch --show-current, then decide whether to keep or discard the work. [1][3]

# 先確認,再保存 / inspect, then keep
git branch --show-current
git switch -c saved-experiment

# 已切走時,只讀尋找 / read-only lookup after leaving
git reflog -10 HEAD

已經切走,還有 reflog / Already left? Check the reflog

如果已經切走,也先別重做。官方文件建議用 git reflog 找回 HEAD 曾指過的提交,再從那個提交建立分支。reflog 是本機參照的移動紀錄,不是會推送到遠端的專案歷史,而且可能依保留設定被清理;所以它是復原線索,不是備份策略。[1][2]

If you already switched away, do not immediately redo the work. The official documentation recommends git reflog to recover a commit previously referenced by HEAD, then creating a branch from that commit. A reflog records local reference movements; it is not project history shared with remotes, and retention settings may eventually prune it. It is a recovery clue, not a backup strategy. [1][2]

本文另外用 Git 2.52.0.windows.1 在暫存測試庫做一次唯讀於專案外的觀察:從第二個提交 detach 到前一個提交後,git branch --show-current 沒有分支名稱;建立 experiment 提交後,git switch -c saved-experiment 讓目前分支回到有名稱的狀態,reflog 也保留那次提交。這只是機制驗證,不代表你的雜湊、分支名稱或保留期限會相同。下次看到 detached HEAD,先判斷是只看舊版,還是已做出要保存的提交;後者先替它建立名稱。

This article also made one observation with Git 2.52.0.windows.1 in a temporary test repository outside the project. After detaching from the second commit to its parent, git branch --show-current returned no branch name. After creating the experiment commit, git switch -c saved-experiment restored a named current branch, and the reflog recorded the commit. This verifies the mechanism only; your hashes, branch names, and retention period will differ. Next time detached HEAD appears, decide whether you are merely inspecting an old revision or have created work worth keeping. In the latter case, give it a name first.

來源與查核 / Sources and verification

查核日期 / Checked: 2026-11-04。前三項為 Git 官方文件;本文另以 Git 2.52.0.windows.1 的暫存測試庫驗證 detach、提交、建立分支與 reflog 流程,不改專案倉庫。 / The first three items are official Git documentation. A disposable repository with Git 2.52.0.windows.1 was also used to observe detach, commit, branch creation, and reflog behavior without modifying the project repository.
  1. Git git-checkout:DETACHED HEAD 與提交保留/復原
  2. Git Data Model:HEAD、分支與 reflog
  3. Git git-switch:--detach 與 -c 範例

留言

熱門文章