Git を1からやり直す(ブランチ編)

Gitを1からやり直す(目次)

ブランチ

branch とは「枝」という意味。履歴を枝分かれさせて開発し、うまくいけば統合させたり、うまくいかなかったら破棄したりということができる。ブランチの概念についてはこういうサイトを見るといいのでは(ブランチとは|サル先生のGit入門【プロジェクト管理ツールBacklog】)。

コマンド 動作など
git branch ブランチ名の一覧を見る
git branch -v ブランチ名の一覧を見る。各ブランチの最新のコミットメッセージなども表示
git branch ブランチ名 新しいブランチを作る
git checkout ブランチ名 ブランチ切り替え。指定したブランチ先端のコミットにHEADが移動する
git checkout -b ブランチ名 新しいブランチを作って、そのブランチに切り替え
git log --all --graph ブランチを見る。 --oneline オプション(1コミット1行表示)あり
git branch -d ブランチ名 ブランチ削除。-d の代わりに -D で強制的に削除

Git - ブランチとは

チェックアウトを詳しく

checkoutは、ブランチ切り替え時に使うことが多いが、指定したコミットをHEADにした上でインデックス(ステージ)と作業ツリーに取り出すときにも使える。

HEAD は現在のコミットを指すポインタのようなものだ。コミットすると、そこを親として新しいコミット(子コミット)ができ、HEADが子コミットに移る。


ブランチ名がmasterだとすると、masterはその一連の履歴という意味で使われることが多いが、masterブランチの先端のコミットという意味もある。HEADと同じように、ブランチの先端を指すポインタのようなものだ。

Gitを1からやり直す(リセット編)

ブランチ名はブランチの先端のコミットを表すので、$ git diff master^ masterのように、コミット指定に使える。

$ git checkout masterは、masterブランチに切り替え先端のコミットをHEADにする。ここでコミットすると、ブランチが伸びてHEADも移る。

checkout関係の新しいコマンドについてはこちらの記事)

masuyama13.hatenablog.com

detached HEAD とは

コミットの指定はHEADブランチ名のほかコミットのハッシュでも可能だ。ただ、チェックアウトの場合は注意が必要。

checkoutは、引数としてブランチ名以外(コミットのハッシュやHEAD^master^など)が渡されると、'detached HEAD'(切り離されたHEAD ) 状態になる。

たとえば、以下のようなリポジトリがあったとする。

$ git log --oneline
ed4ef63 (HEAD -> master) English追加
a67591b READMEに"▲▲▲▲"追加
4d7d34c READMEに"〇〇〇〇"追加
22b74e1 README作成

ここで、1つ前のコミットmaster^をチェックアウトしてみる。

$ git checkout master^
Note: checking out 'master^'.

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 a67591b READMEに"▲▲▲▲"追加

このように、'detached HEAD' 状態になっているという注意書きが表示される。

'detached HEAD' とは、HEADがどのブランチの先端とも一致していない状態のこと。ここでコミットしてもどのブランチも伸びないので、HEADがそこから離れると普通の方法ではアクセスできなくなりいずれ削除される。

コミットのハッシュで指定すると、それがたとえHEADやブランチ先端のコミットと同じものであったとしても 'detached HEAD' になってしまう。

さっきのログで、masterブランチの先端かつHEADはed4ef63$ git checkout ed4ef63は 'detached HEAD' になる。'detached HEAD' になると、HEAD -> masterだったのが、以下のようにHEAD, masterに変わる。

$ git log --oneline
ed4ef63 (HEAD, master) English追加
a67591b READMEに"▲▲▲▲"追加
4d7d34c READMEに"〇〇〇〇"追加
22b74e1 README作成

git statusでも確認できる。

$ git status
HEAD detached at ed4ef63
nothing to commit, working tree clean

'detached HEAD' 脱出方法

'detached HEAD' になるときGitは上のように警告を出してくれるので、気づかないということはまずないだろう。そこにコミットしたいのであれば、Gitが書いてくれているように$ git checkout -b <new-branch-name>で新しいブランチを作ればいい。

'detached HEAD' 状態を脱するには、$ git checkout masterなどでブランチ先端に戻ればOK。


(参考資料)わかる Git