git checkout でブランチ切り替え。仕様とオプションまとめ

最終更新:2018-10-12 by Joe

git checkout について、動作仕様とオプションについてまとめました。またリモートブランチへの切り替えにおけるよくある誤解と、その解決方法について記載しました。

git checkout の概要

「git checkout」は下記の2つの機能を持ったコマンドです。

git checkout の機能

  1. 作業ブランチを切り替える
  2. 指定したコミット(もしくはインデックス)の状態を、現在の作業ツリーに展開する

もしパラメータに「ブランチ名」を指定すれば、[1]の動作、ファイルパスやファイル名を指定すれば、[2]の動作となります。この2つは異なる機能ですので、注意が必要です。

作業ブランチを切り替える

git checkout コマンドに、パラメータでブランチ名を指定すれば、そのブランチに切り替える事ができます。

// masterブランチに切り替える
git checkout master

git checkout によるブランチ切り替え

なお、ブランチ切り替え時に、作業ツリーやインデックスに変更内容が残っており、かつチェックアウト先のファイルとの間で、残っている変更内容がコンフリクトするのであれば、エラーとなりブランチ切り替えを中止します。

git checkout によるブランチ切り替えのエラー
作業ツリーに変更が残っていたため、エラーメッセージとともにブランチ切り替えが中断された。

逆に、コンフリクトが発生しないのであれば、変更を作業ツリーや、インデックス上にそのまま維持できます

指定したコミットにおける任意のファイルを作業ツリーに反映する

git checkout のパラメータに、コミットとパス(ファイル名)を指定すれば、作業ツリーにファイルを展開するコマンドとして動作します。パラメータの違いで、[1]とは少し異なる動作をしますので、それぞれの機能を混同しないように注意して下さい。

さて、引数にはコミット識別子を直接指定しても構いませんし、例えば「HEAD」のような参照でももちろんOKです。

// 例1:コミット「6f87gs1」の index.php を、作業ツリーに展開するコマンド
git checkout 6f87gs1 index.php

// 例2:HEAD の index.php を、作業ツリーに展開するコマンド
git checkout HEAD index.php

git checkout によるファイルの作業ツリーへの展開

もしコミット指定を省略して、パス(ファイル名)のみを指定すれば、代わりにインデックス上のファイルを作業ツリーに展開します。

// インデックスの index.php で、作業ツリーに展開するコマンド
git checkout index.php
git checkout におけるファイルパスの指定方法

git checkout コマンドのファイルパスの指定では、コミットとファイルパスの間に「–」を含めても構いません。例えば・・・

// 現在のブランチの先頭の index.php を、作業ツリーに展開する
git checkout HEAD -- index.php

この記述は、めんどうですので省略する事がほとんどです。

ただ万が一、「インデックスの masterというファイルを作業ツリーに展開したい」のであれば下記のように書く事でmasterブランチでなくファイル名のmaster であることをGitに伝える事ができます。

// インデックスの master を作業ツリーに展開する
git checkout -- master

でも、これが必要となる状況と遭遇することは、まず発生しないでしょう・・・。

git checkout のオプション

git checkout の主要なオプションの紹介です。いくつかのオプションは、ブランチを新規生成する機能がふくまれており、そのため、git branch コマンドと共通のオプションも存在します。

新規ブランチをチェックアウト「git checkout -b」

新規ブランチを作成する、同時にチェックアウトする「-b」オプションは、git checkout で最も利用頻度の高いオプションです。

これは「git branch <ブランチ名>」と「git checkout <ブランチ名> 」のショートハンドとして動作します。また、git branch コマンドのように、ブランチ作成の起点を第二パラメータで指定できます。

// 例)現在のブランチの先頭から、new-feature ブランチを作成してチェックアウト
git checkout -b new-feature

// 例)master を起点に、favorite-feature ブランチを作成してチェックアウト
git checkout -b favorite-feature master

もし、すでに存在するローカルブランチ名であれば、新規ブランチとしては作成できませんが、大文字の「-B」オプションで、強制的に新規ブランチとして再生成し、そこに切り替えることができます。

// dev ブランチがすでに存在しても、強制的に master に合わせて、チェックアウトする
git checkout -B dev master

強制的にチェックアウト「git checkout -f 」

ブランチ切り替え時に、作業ツリーやインデックスに変更が残っていれば、エラーにより、ブランチ切り替えは中断します。一方で、そのような変更をすべて破棄してもよければ、「-f」オプションにより強制的にチェックアウトできます。

// インデックスと作業ツリーの変更を破棄して、強制的にチェックアウトする
git checkout -f master

【参考】リモートブランチは checkoutできるの?

リモートブランチを更新したいとき、ついローカルブランチのようにチェックアウトして編集したくなってしまうかもしれません。ですが、git の仕様上、作業ブランチをリモートブランチに切り替えて、直接更新することはできません

ローカル環境からリモートブランチを更新する唯一の手段は「ローカルブランチの履歴を、リモートブランチに push する」のみとなります。通常リモートの更新には、下記のような手順を操作を行います。

リモートブランチを更新する手順

  1. リモートブランチに対応する「リモート追跡ブランチ」をローカルに作成
  2. 作成したローカルブランチを作成してチェックアウト
  3. 対応するリモートブランチにPush

1リモートブランチに対応する「リモート追跡ブランチ」を作成する

例えば、リモート「origin」にある「cool-feature」というブランチを更新する場合、git fetch コマンドを使って対応するリモート追跡ブランチを作成します。

// リモートの cool-feature ブランチに対応する追跡ブランチを作成
git fetch origin cool-feature

この時点で、まだ作業用のブランチは作られておらず、リモート追跡ブランチ「origin/cool-feature」が存在するのみです。

2作業用ローカルブランチを作成し、チェックアウトする

[1]を終えた状態で、、下記のように git checkoutコマンドを使えば、自動的に同名のリモート追跡ブランチを起点にして、ローカルブランチを新規生成し、チェックアウトできます。

// リモートのcool-featureブランチをフェッチする
git checkout cool-feature

cool-feature は、まだ存在しないブランチ名は「-b」オプションなしにはチェックアウトできないはずですが、指定した「cool-feature」が「origin/cool-feature」とローカルに見つかりますので、この場合、自動的にそのリモート追跡ブランチを起点にして、新しいローカルブランチが作られてくれます。git の親切設計です。

さらに、この方法を使うと、同時に cool-feature ブランチの上流ブランチ(upstream branch と言います)として「origin/cool-feature」が設定されます。これは「git checkout -b <branch> --track <remote>/<branch>」と明示した時と同じ動作となります。

リモート追跡ブランチからローカルブランチを作成してチェックアウト
コマンド実行後、上流ブランチとして設定された由がメッセージで表示される。

ご参考まで、「上流ブランチ」の概念に関してはこちらをご一読下さい。

3ローカルブランチの変更内容をPushする

あとはPushすればOKです。[2]ですでに上流ブランチが設定されていますので、git push のパラメータは省略できます。

// cool-featureの状態を、対応する上流ブランチにPUSHする 
git push 
git push origin cool-feature // 同義
試しにリモートブランチをチェックアウトしてみる...

改めて、抑えておく必要があるのは「リモートにあるブランチをチェックアウトする」はできないですし、「リモート追跡ブランチをチェックアウトしてそこで作業する」もできない、という点です。

でも、好奇心で、試しにリモート追跡ブランチをcheckoutしてみたらどうなるでしょうか。

$ git checkout origin/cool-feature

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 91f6913... iUpdate the style.

「Detached HEAD状態」になってしまいました。これは、いわば「匿名ブランチにいる状態」という所で、つまるところ、origin/cool-featureをチェックアウトしてそのブランチで作業できていない(匿名ブランチに乗っている)ということですね。もし、新しいブランチで作業したければ、ちゃんと-bでローカルブランチ作ってね、というただし書きまであります。

ただ「一時的にリモートの状態をローカルで動作させたい」などのテスト目的であれば、あえてこのように匿名ブランチで作業するもの選択肢かもしれませんね。匿名ブランチ上で行った変更はすべてブランチを切り替えなおすと同時に破棄されます。

参考情報

git checkout に関する、Gitの公式ドキュメントです。