【 git checkout 】コマンド(応用編)――ワークツリーを特定のブランチやコミットに切り替えるLinux基本コマンドTips(392)

本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回はGitについて、ワークツリーを特定のブランチやコミットに切り替える「git checkout」コマンドです。

» 2020年04月30日 05時00分 公開
[西村めぐみ@IT]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「Linux基本コマンドTips」のインデックス

Linux基本コマンドTips一覧

 本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は基礎編に続き、Gitについてワークツリーを特定のブランチやコミットに切り替える「git checkout」コマンドです。

git/git checkoutコマンドとは?

 「git」は「Git」という分散型バージョン管理システム用のコマンドです。Gitは元々Linuxカーネルのソースコードを管理するために作られた「バージョン管理システム」で、現在は多くのソフトウェアやWebサイトのソースコード、ドキュメントの管理などに用いられています。

 ソースコードを管理する際、最新版だけを保存するやり方はうまくいきません。開発中のさまざまなタイミングで状態を管理し、必要に応じて比較、参照したり、元に戻したりできるようにする仕組みが「バージョン管理システム」です。

 Gitでは、テスト版など複数に枝分かれした状態も管理できます。複数のメンバーによる開発を前提としており、開発中の各時点におけるコメントや、コメントへの返信なども管理できるようになっています。

gitのサブコマンドとGitの仕組み

 gitコマンドはほとんどの場合、「サブコマンド」と組み合わせて利用します(本連載ではgitとサブコマンドの組み合わせをコマンドとして紹介します)。

 今回紹介する「git checkout」はワークツリーを特定のブランチやコミットに切り替えたり、特定のコミットからファイルを取り出したりするコマンドです。連載第391回ではブランチの切り替えを扱いました。今回は、コミットを指定することで、古いバージョンにさかのぼる方法を取り上げます。

 gitコマンドが扱う「リポジトリ(repository)」とは、ソースコードや変更履歴、コメントなどを一括して保管する場所です。リポジトリには、自分のPC上に作る「ローカルリポジトリ」と、「GitHub」などのWebサービス上に作る「リモートリポジトリ」があり、両者を連携させることで複数の開発者による開発を1本にまとめることができます。

 既存のリポジトリ(リモートリポジトリ)にあるソースコードなどを入手したい場合は、まず、「git clone」(連載第381回)でリポジトリを自分の環境に複製します(※1)。リモートリポジトリの内容がバージョンアップされたら「git pull」(連載第382回)コマンドで最新版を取得します。開発に参加するのではなく、単に最新版を取得したいという場合は、「git clone」と「git pull」を利用すればよいでしょう。

※1 特定のファイルだけが欲しい場合、例えばGitHub(github.com)にあるリポジトリであれば「Raw」というボタンで表示されるURLを使い、「wget」コマンドなどを使ってダウンロードできる。この他、プロジェクト全体をダウンロードするためのリンクも用意されている([Clone or download]ボタン→「Download ZIP」)。



 保管場所であるリポジトリに対し、ファイルの編集などを行う場所を「ワークツリー」「ワーキングエリア」「作業ツリー」などと呼びます。「git clone」や「git pull」で取得した最新版のファイルはワークツリーに配置されます。つまり「作業ディレクトリ」です。

 ワークツリーで編集した結果をリポジトリに反映する操作を「コミット」と呼びます。「git add」(連載第384回)コマンドでコミットしたいファイルを「インデックス」あるいは「ステージングエリア」と呼ばれる領域に追加します。インデックスにはファイルの変更箇所などが記録されます。

 インデックスの内容は「git commit」コマンドでローカルリポジトリにコミットされ、「git push」コマンドでローカルリポジトリの内容をリモートリポジトリに反映します。従って、「git add」や「git commit」などを行わなければ、自分の環境で編集した内容がリポジトリに影響を与えることはありません。自由に編集し、テストできます。なお、ワークツリーのファイルを過去の任意のコミット状態に戻すことも可能です。

 Gitには、この他、開発中のソースコードやドキュメントを、「テスト版」「○○版」……のように枝分かれさせたり、それらを合流させたりする機能もあります。枝分かれしたそれぞれのバージョンを「ブランチ」(branch)と呼び、ブランチを合流させることを「マージ」(merge)と呼びます。



コマンドの書式

git [オプション] サブコマンド [サブコマンドごとのオプションや引数]

git checkout [オプション] [対象]

git checkout [オプション] [対象] -- ファイル

※ 「対象」にはファイル名やブランチ、タグ、コミットのハッシュ値などが指定可能。[ ]は省略可能な引数を示しています。




gitの主なオプション

短いオプション 長いオプション 意味
-C パス カレントディレクトリではなく指定したディレクトリで実行したものとする
--bare リポジトリを「bareリポジトリ」(ワーキングディレクトリが存在しない、管理だけを目的としたリポジトリ)として扱う
-c 設定=値 設定値を指定する(設定は「git config」で確認可能)
-p --paginate 全ての出力を「less」コマンドまたは環境変数PAGERで指定されたコマンドで表示する
-P --no-pager 「less」コマンドで表示しない(「-p」の指定を打ち消す)
--exec-path=パス gitの実行ファイルのパスを指定する(「--exec-path」のみの場合、実行ファイルのパスを表示する)
--html-path gitのHTML形式のドキュメントがインストールされたパスを表示する
--man-path gitのmanファイルのパスを表示する
--info-path gitのinfoファイルのパスを表示する

gitのサブコマンド

コマンド 実行内容
clone リポジトリのクローンを作成する
init リポジトリを新規作成する、または既存のリポジトリを初期化する
remote リモートリポジトリを関連付けする
fetch リモートリポジトリの内容を取得する
pull リモートリポジトリの内容を取得し、現在のブランチに取り込む(「fetch」と「merge」を行う)
push ローカルリポジトリの変更内容をリモートリポジトリに送信する
add ファイルをインデックスに追加する(コミットの対象にする)
rm ファイルをインデックスから削除する
mv ファイルやディレクトリの名前を変更する
reset ファイルをインデックスから削除し、特定のコミットの状態まで戻す
status ワークツリーにあるファイルの状態を表示する
show ファイルの内容やコミットの差分などを表示する
diff コミット同士やコミットとワークツリーの内容を比較する
commit インデックスに追加した変更をリポジトリに記録する
tag コミットにタグを付ける、削除する、一覧表示する
log コミット時のログを表示する
grep リポジトリで管理されているファイルをパターン検索する
branch ブランチを作成、削除、一覧表示する
checkout ワークツリーを異なるブランチに切り替える
merge 他のブランチやコミットの内容を現在のブランチに取り込む
rebase コミットを再適用する(ブランチの分岐点を変更したり、コミットの順番を入れ替えたりできる)
config 現在の設定を取得、変更する

git checkoutの主なオプション

短いオプション 長いオプション 意味
-p --patch 一つ一つの差分を確認しながらチェックアウトを進める(第392回参照)
-q --quiet メッセージを表示せずに実行する
-f --force インデックス(ステージングエリア)やワークツリーに変更があっても構わずに実行する(インデックスやワークツリーの変更内容を破棄する)
--ours コンフリクト(※2)が発生したら、現在修正している側(ローカル側)の変更を優先させる
--theirs コンフリクト(※2)が発生したら、リモート側の変更を優先させる
-b ブランチ名 [対象] 対象のチェックアウト後に、新しいブランチを開始する(※3)
-B ブランチ名 [対象] 対象のチェックアウト後に、新しいブランチを開始する。指定した名前のブランチが既にあった場合はリセットする(「-b」の場合はエラーになる)
--orphan ブランチ名 空のブランチを作成する

※2 同じブランチの異なるコミットでチェックアウトを実行した場合、ワークツリーとマージする。しかし同じ箇所に変更があった場合には「コンフリクト(衝突)」と呼ばれる状態となり、どちらを優先するか判断する必要がある。コンフリクトはファイルを閲覧しているだけの場合には発生しない。
※3 ブランチの作成についてはこの後の連載であらためて取り上げる。





コミットを指定してチェックアウトする

 「git checkout コミット」で指定したコミット時点の状態に、ワークツリーの内容を変更します。コミットはハッシュ値またはタグで特定します。

 コミットのハッシュ値を使用する場合、40桁全てではなく、冒頭の数文字で指定できます。「git log --oneline」でログを一覧表示すると、ハッシュ値の冒頭部分を表示します(※4)。ここに表示されている値だけでコミットを指定可能です。

※4 特定できる範囲の省略形(デフォルトは先頭7バイト分)で表示される。



 git checkoutコマンドでブランチではなくコミットを指定した場合、ブランチの先頭から切り離された「detached HEAD」と呼ばれる状態になります。ワークツリーを参照するだけであればこの状態でも問題はありません。

 修正してコミットしたい、という場合は、「-b」または「-B」オプションを使って別のブランチに枝分かれさせるとよいでしょう。今後の連載でブランチの作成方法を取り上げます。

 ブランチの最新の状態に戻すには「git checkout ブランチ」のように、ブランチ名を指定します。

 なお、以下のコマンドの実行例では前回に引き続き「progit2-ja」を使用しています。「git clone https://github.com/progit/progit2-ja」で自分の環境に複製を作り(連載第381回)、ワークツリーであるprogit2-jaディレクトリの中で実行しています。

コマンド実行例

git checkout ハッシュ値

(ワークツリーの内容を、ハッシュ値で指定したコミット時点の状態に戻す)

git checkout タグ

(ワークツリーの内容を、タグで指定したコミット時点の状態に戻す)

git checkout ブランチ

(ワークツリーの内容を、指定したブランチの最新の状態に更新する)

git checkout master

(ワークツリーの内容を「master」ブランチの最新の状態に更新する)


 画面1では、まず、「git status」で現在の状態を確認しています。次に「ls」コマンドでワークツリーにどのようなファイルがあるのかを確認しました。最後に、「git log --oneline -10」(連載第386回)で直近10回分のコミットを表示しています。

画面1 画面1 現在の状態を確認したところ

 画面2では、「git tag」で現ブランチのタグを一覧表示しました。

画面2 画面2 全てのタグを表示したところ

 画面3では、「git checkout 2.0.0」で「2.0.0」タグを付けたときの状態にワークツリーを戻しています。

画面3 画面3 特定のタグを時点にワークツリーを戻したところ

 画面4では、「git checkout master」でワークツリーの内容を「master」ブランチの最新の状態に更新しました。

画面4 画面4 masterブランチの最新の状態に更新したところ


ファイルを指定してチェックアウトする

 「git checkout ファイル」のように、ファイルを指定してチェックアウトを実行できます(画面5)。ワークツリーでの編集を破棄して、現在のコミットの状態に戻したいときに便利なコマンドです。

 例えば、ワークツリーの「dir1/file1.txt」を編集した後に「git checkout dir1/file1.txt」を実行すると、コミット時の「dir1/file1.txt」に戻ります。

 コミットとファイル名を同時に指定したい場合は「git checkout タグ -- ファイル名」のように、「--」の後にファイル名を指定します(※5)。

※5 「--」は、以降の指定がファイル名であることを明示するための記号だ。指定内容によっては「git checkout tagname dir1/file1.txt」のように「--」を付けなくても問題ない。



コマンド実行例

git checkout ファイル

(指定したファイルをチェックアウトする。ファイルはワークツリー内のパスで指定する)

git checkout dir1/file1.txt

(ワークツリーのdir1/file1.txtを、コミット時の内容に戻す)

git checkout タグ -- dir1/file1.txt

(ワークツリーのdir1/file1.txtを、指定したタグの時点のdir1/file1.txtの内容に戻す。タグ以外にハッシュ値でも指定できる)


画面5 画面5 指定したファイルをコミット時の内容に戻したところ

 画面6では、準備のために「8f5156f」(画面1のgit logで表示)で修正した「git-daemon.asc」の内容を確認しています。

画面6 画面6 画面7で使うファイルの修正内容を確認したところ

 画面7では、さまざまなタイミングのコミットを指定してチェックアウトを試みています。

画面7 画面7 さまざまな指定方法でチェックアウトを試みたところ 「8f5156f^」で、ハッシュ値8f5156で指定したコミットの変更元を指定している


筆者紹介

西村 めぐみ(にしむら めぐみ)

元々はDOSユーザー。ソフトハウスに勤務し生産管理のパッケージソフトウェアの開発およびサポート業務を担当、その後ライターになる。著書に『図解でわかるLinux』『らぶらぶLinuxシリーズ』『[新版 zsh&bash対応] macOSコマンド入門』『Accessではじめるデータベース超入門[改訂2版]』など。地方自治体の在宅就業支援事業にてMicrosoft Officeの教材作成およびeラーニング指導を担当。会社等の"PCヘルパー"やピンポイント研修なども行っている。


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。