Gitで過去のコミットやタグをチェックアウトしたときに発生するのがdetached HEAD
状態です。
この状態ではHEADが特定のブランチを指しておらず、直接コミットを積んでもブランチに反映されません。
本記事では、この状態から元の作業ブランチに安全に戻る方法と、誤って作業内容を失わないための対処法を解説します。
detached HEADとは
通常、HEADは作業ブランチの先頭コミットを指していますが、特定のコミットハッシュやタグを直接checkout
すると、
HEADがブランチから切り離された状態になります。これがdetached HEAD
です。
# 例:過去のコミットを直接チェックアウト
git checkout a1b2c3d
# またはタグをチェックアウト
git checkout v1.0.0
この状態で作業してコミットを積んでも、そのコミットはどのブランチにも属さず、参照が途切れると失われる危険があります。
現在の状態を確認する
まずは今の状態を把握します。git status
でHEAD detached at ...
と表示されていれば、detached HEAD状態です。
git status
どのブランチからこの状態に来たかを知りたい場合は、git reflog
でHEADの移動履歴を確認できます。
git reflog
出力例:
e3f1a2b HEAD@{0}: checkout: moving from main to a1b2c3d
...
a1b2c3d HEAD@{1}: checkout: moving from feature/login to main
この例ではHEAD@{1}
の行に元いたブランチ(main)が記録されています。
元の作業ブランチに戻る
元のブランチ名がわかっている場合は、単純にgit switch
またはgit checkout
で戻ります。
# ブランチが分かっている場合
git switch main
# または
git checkout main
ブランチ名を忘れた場合は、git reflog
で履歴を確認して該当ブランチに戻ります。
# reflogで元のブランチを確認して戻る
git switch -
git switch -
は直前にいたブランチへ戻るショートカットです。
detached HEAD状態で作業をしてしまった場合
detached HEAD状態で新しいコミットを作成した場合、そのままブランチに戻ると作業内容が参照されなくなる可能性があります。
この場合は、作業内容を保持するために新しいブランチを作成してから戻ります。
# 現在の作業を新しいブランチとして保存
git switch -c temp-work
# その後、元のブランチへ戻る
git switch main
こうすることで、detached HEAD状態で積んだコミットもブランチに紐付けられ、失われなくなります。
detached HEADを避けるためのポイント
履歴を一時的に確認したいだけなら、git show
やgit log -p <commit>
など、ブランチ移動を伴わない方法を使うと安全です。
また、特定の状態から作業を始める場合は、必ず新しいブランチを切ってから開始しましょう。
# 特定コミットから新しいブランチを作成
git switch -c fix-bug a1b2c3d
まとめ
detached HEAD状態から元の作業ブランチに戻るには、git switch ブランチ名
またはgit switch -
を使います。
作業中のコミットを失わないためには、新しいブランチにしてから戻るのが安全です。
reflogで過去の移動履歴を確認すれば、元のブランチや状態を特定できます。