いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

detached HEAD状態から元に戻すコマンド (git, checkout, fix a detached HEAD, .git/HEAD, refs/heads/master)

gitにて、意図せずにdetached HEAD状態になってしまった場合に元に戻る方法についてメモメモ。


git触っていて、たまにdetached HEAD状態に突入してしまうことがあります。(私の場合)
大抵は、checkoutで特定のコミットを指してしまった場合です。


detached HEADは、そのまんま「デタッチ状態のHEAD」です。
デタッチはアタッチの逆なので、これもそのまんま「切り離された状態」という意味になります。


でも、この状態になるとgitが警告メッセージを表示してくるので、いきなりなるとアセりますw
具体的には以下のようなメッセージが表示されます。

# リポジトリ初期化
git init

# 適当にファイル追加してコミット
touch test.txt
git add -A
git commit -m "add"
git commit -am "mod"

# 現在, masterとHEADは同じコミットを指している
#   .git/HEADをみると「ref: refs/heads/master」となっている。
#   つまり、HEADはmasterを指している.
# ここでHEADを動かすと detached HEAD になる
#   (checkoutを実行した後、再度 .git/HEADを見るとmasterではなく特定のコミットを指すようになっている)
git checkout HEAD^
  Note: checking out 'HEAD^'.

  You are in 'detached HEAD' state. You can look around, make experimental
  changes and commit them, and you can discard any commits you make in this
  state without impacting any branches by performing another checkout.

  If you want to create a new branch to retain commits you create, you may
  do so (now or later) by using -b with the checkout command again. Example:

    git checkout -b new_branch_name

  HEAD is now at 3f1ce05... add

なんか、怖そうなメッセージが表示されていますね。
これはdetached HEAD状態になったのでgitが教えてくれています。
で、問題のdetached HEADの状態から元に戻る件ですが、実は正解をgitがメッセージの中で教えてくれています。


上のメッセージを適当ですが拙訳すると、こんな感じです。

'detached HEAD'状態になりましたー。(この状態は他のブランチから切り離されている(デタッチ)ので)ファイルを見て回ったり
実験的な変更を加えたりしても大丈夫ですよ−。んで、別のブランチにcheckoutすると、他のブランチに影響を与えることなく
detached HEADで行った変更を捨てられますよ−。

もし、変更を残したい場合は、今すぐでも後でもいいので、-bオプション付きでcheckoutコマンドを実行してくださいー。
例:
    git checkout -b new_branch_name

今のHEADは 3f1ce05... add ですよ。


実は、親切にgitが教えてくれています。なので、元の状態に戻りたい場合は

git checkout master


ってすれば戻ります。で、戻る際にdetached HEADで変更した状態のまま
戻ろうとすると、gitがまた教えてくれます。(gitちゃん、やさしい・・)

git checkout master
  Warning: you are leaving 1 commit behind, not connected to
  any of your branches:

    d7ab62c mod2

  If you want to keep them by creating a new branch, this may be a good time
  to do so with:

   git branch new_branch_name d7ab62c1ed27068bbb00ca13ada147293f82110c

  Switched to branch 'master'

上のメッセージも拙訳すると、こんな感じです。

どのブランチとも繋がっていないコミットを1個残してますよ−。

  d7ab62c mod2

もし、これを残しておくのであれば、今がちょうどいいタイミングですよー。
以下を実行すれば残しておけますよー。

  git branch new_branch_name d7ab62c1ed27068bbb00ca13ada147293f82110c

'master'ブランチにスイッチしましたー。


以下、参考リソースです。


================================
過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。