Lesson 3
基本操作
Lesson 3
Chapter 1
更新系のコマンド
Lesson2ではGitのインストールやリポジトリの作成などの事前準備を行ってきました。Lesson3では実際の業務でも利用機会の多い実践的な各Gitコマンドを学んでいきましょう。 まず、更新系のコマンドについて説明をしていきたいと思います。
git checkout
git checkout(チェックアウト)とは、「ブランチ」を切り替えるためのコマンドです。「checkout」は英語で、「出ていく」、「出発する」、「去る」などの意味を持ちます。つまり、いま自分のいる場所を出て、別の場所に移動するイメージを持っていただければと思います。
ブランチとは
ここで、初めて出てきた単語である「ブランチ」についても説明をします。ブランチとは、枝分かれした、それぞれの作業内容の履歴のことです。「branch」は英語で、「木の枝」という意味を持ちます。
実際のソフトウェアの開発では、新機能を開発しながら、既存のバグの修正を行なったりなどの作業を同時並行して行うことが多いです。しかし、例えば、それらを同じソースコードに対し編集を加えることで、新機能の開発の内容が、既存のバグの修正側の作業に影響を与えてしまったり、逆に影響を受けてしまうことで、予期せぬバグを発生させてしまう心配があります。
つまり、他の作業に影響を"与えない"かつ"受けない"という仕組みが必要となります。ブランチを用いることでこれらの課題を解消することができます。
まとめると、ブランチには以下のようなメリットがあります。
-
開発の目的ごとにソースコードに独立した変更を加えることができる
-
並行して複数機能を開発することができるため、チームでの開発が行いやすくなる
以下のイメージ図では、ブランチ①とブランチ②という2つのブランチが存在しています。「作業1」、「作業2」まではどちらのブランチでも作業の履歴が一致していますが、それ以降はブランチ①とブランチ②で枝分かれしており、別々の作業を行なっています。
この時、ブランチ①の「作業3」、「作業4」は、ブランチ②には影響せず、反対に、ブランチ②の「作業5」、「作業6」は、ブランチ①には影響しないようになっています。
複数ブランチでの作業のイメージ
このように、ブランチを分ける(枝分かれする)ことで、それぞれの作業が独立して開発を進めることができるので、チームでの開発をより効率的にすることができます。また、ブランチが分かれることで、一方のブランチでの作業履歴や別のブランチでの作業履歴を分けて確認、管理することができるため、開発の目的ごとに作業の管理がしやすくなります。
ブランチは、gitの仕組みの中でも非常に重要な機能の1つですので、しっかりと理解をしておきましょう。
また、Lesson2で、ご自身のリモートリポジトリをgit cloneし、手元のマシンにローカルリポジトリを作成しましたが、この時点ではリポジトリ内にまだ何もブランチは存在しておらず、何か変更内容を登録すること(この操作を「コミット」と呼びます。)で、master(main)ブランチというブランチが作成されます。
コミットについて
「コミット」についてはこの後の「git commit」の項目にて説明します。
master(main)ブランチは、統合ブランチとも呼ばれ、基本的に安定した状態を保っておくことが重要です。開発を進めるにあたり、
①統合ブランチであるmaster(main)ブランチから開発用のブランチを作る
②開発用のブランチに移動して開発を行う
③開発用のブランチで行った作業内容をmaster(main)ブランチに統合していく
というのがざっくりとしたGitを使ったチーム開発での一般的な流れとなります。
作業内容を統合するイメージ
ブランチには、開発の目的に応じて様々なブランチが存在します。
ブランチの運用方法について
ブランチの運用方法等の詳細についてはLesson4にて詳しい説明を行います。
master(main)ブランチの名称変更の動きについて
これまでは「master」がデフォルトの名前でしたが、人権運動を背景に、今後は「main」に変わっていく流れになってきています。GitHubではすでに「main」表記になっているため、それに倣い、本レッスンでも「main」ブランチと記載したいと思います。
git checkoutの説明に戻りますが、以下のようにgit checkoutの後にブランチ名を指定することでブランチを切り替えることが可能です。
git checkout (指定のブランチ名)
例えば、いまいるブランチがmainブランチの状態で、開発用のdevelopmentブランチに移動したい場合は以下のように実行します。
git checkout development
git pull
git pull(プル)は、リモートリポジトリから最新の状態を手元のローカルリポジトリに反映するためのコマンドです。以下のようにgit pullの後にリモートリポジトリのアクセス先とブランチ名を指定します。
git pull (リモートリポジトリのアクセス先)(指定のブランチ名)
git pullのイメージ
実際に動かして試してみたいと思いますので、Lesson2で作成したリモートリポジトリ「https://github.com/(ご自身のGitHubアカウント名)/test-remote-repositry.git」にて、適当なファイルを追加し、最新になった状態のリモートリポジトリをローカルへgit pullしていきたいと思います。
それでは、GitHub上でリモートリポジトリ(以下の添付画像)を表示し、赤枠の「creating a new file」リンクをクリックしてください。
以下のページが表示されるので、赤枠の箇所に「test.html」と入力し、Edit new file欄に「テスト」と記述します。
ページ一番下までスクロールし、ご自身のアイコンの右のCommint new fileの下に表示されている赤枠の「Create new file」欄にて「リモートリポジトリでテストファイルの作成」と入力し、「Commit new file」の緑色のボタンを押下してください。
すると、以下のページに遷移します。これは1枚目の添付画像と同じ「Code」タブの画面になりますが、元々リポジトリ内にファイルが1つも無い空の状態から、実際にファイルが追加されたことで、以下のように変化します。先ほど作成した「test.html」が表示されているのが分かります。
無事にリモートリポジトリでファイルが作成できましたので、続いてその内容をローカルリポジトリへ反映していきたいと思います。
再度文法をおさらいしますと、リモートリポジトリから最新の状態を手元のローカルリポジトリに反映するためのコマンドは以下になります。git pullの後に「リモートリポジトリのアクセス先」と「ブランチ名」を指定します。
git pull (リモートリポジトリのアクセス先)(指定のブランチ名)
つまり、以下のようなコマンドを実行することになります。
git pull https://github.com/(ご自身のGitHubアカウント名)/test-remote-repositry.git main
ただ、これでは、毎回git pullを実行するたびに、リモートリポジトリのURLを入力することとなり、面倒です。
ただ、今回は元々リモートリポジトリからgit cloneを実行して、ローカルリポジトリを作成していました。
この場合、すでにローカルリポジトリとリモートリポジトリが自動的に対応するような仕組みになっています。そのため、以下のコマンドを実行することで、ローカルリポジトリに紐づくリモートリポジトリを確認することができます。
git remote -v
実際にコマンドを実行してみると以下のような出力結果が得られます。
git remote -vコマンドの実行結果
つまり、ローカルリポジトリには「origin」というリモートリポジトリのアクセス先が存在し、その「origin」という名前に対して、リモートリポジトリが設定されている、という意味になります。
originについて
「オリジン」と読みます。git cloneなどでリモートリポジトリからローカルリポジトリを複製した場合に、ローカルリポジトリに対応するリモートリポジトリのアクセス先についてはGit側がリデフォルトで「origin」と名前を付けるようになっています。また、慣習として、ローカルリポジトリ側から手動でアクセス先のリモートリポジトリを設定する際にも"origin"と設定することが多いです。
そこで、リモートリポジトリのアクセス先である「origin」という名前を利用し、以下のように短くすっきりとしたコマンドでgit pullを実行することができます。
git pull origin main
さらに、上記のように毎回git pullの後に「リモートリポジトリのアクセス先」と「ブランチ名」の記述を省略することも可能です。
以下のようにpullとoriginの間に「-u」を付けてコマンドを実行することができます。
「-u」は「upstream」の略であり、「上流」という意味です。
「-u」を付けることでローカルリポジトリに対し上流ブランチを設定することができます。
上流ブランチとは、ローカルリポジトリに対応するリモートリポジトリのことです。つまり、ローカルリポジトリのmainブランチの上流のブランチにリモートリポジトリのmainブランチを設定する、というコマンドとなります。
git pull -u origin main
このコマンドを一度実行しておくことで、現在チェックアウトしているブランチがmainブランチの場合、次回からはgit pullのみを実行することで、リモートリポジトリのmainブランチをローカルリポジトリに反映することができますので、ぜひ覚えておきましょう。
git add
git add(アド)は、ワークツリーからステージエリアにファイルやディレクトリを追加するコマンドです。「add」は英語で「追加する」という意味です。
git addのイメージ
ワークツリーとは
Gitの管理下に置かれたディレクトリのことです。ワークツリーは、「作業ディレクトリ」、「ワーキングツリー」と呼ばれることもあります。
例えば、Lesson2で作成したリモートリポジトリ「test-remote-repositry」では、そのリポジトリ内部に存在しているディレクトリやファイルが基本的にすべてGitの管理下に置かれています。
先ほど、作成したtest.htmlもGitによって管理されている状態となり、同時にワークツリー内に存在しているファイルでもあります。
ステージエリアとは
この後に説明する「コミット」という操作により、Gitリポジトリに当該作業を履歴として記録される前に、一旦ファイルが配置される領域のことです。行なった作業の変更をリポジトリに記録をする前の準備をするために必要なエリアと思っていただければと思います。「ステージングエリア」と呼ぶこともあります。
ステージエリアが存在するメリット
ワークツリーから直接Gitリポジトリに変更内容を記録するのではなく、中間にステージエリアが存在するメリットについてですが、ワークツリーに存在するすべてのディレクトリ、ファイルの中から、とある作業を行なった際に必要な変更が入ったディレクトリ、ファイルのみを一旦ステージエリアに上げることができることにより、
「行なった変更作業の内容を局所化しやすくなり、バージョン管理がしやすくなる」
といった点が挙げられます。
git addの説明に戻りますが、ワークツリーでファイルを編集した後は、まずこのコマンドを実行し、変更を記録したいファイルをステージエリアに追加します。
以下のようにgit addの後に対象のファイル名を指定して実行します。
git add (対象のファイル or ディレクトリ名)
ここで、実際にローカルリポジトリに存在するtest.htmlを編集し、それをgit addしてみたいと思います。エディタを起動し、お手元のマシン内のローカルリポジトリ「test-remote-repositry」のディレクトリにあるtest.htmlを開いてください。
test.html
このように、前回git pullした内容が反映された状態になっているかと思います。続けて文章を追加し、ファイルを編集していきます。3行目に以下のように文章を追加しました。
test.html
仮にこれで必要な変更作業が完了したとして、続けてgit addを実行し、ワークツリーに存在するtest.htmlをステージングエリアに追加していきます。
git add test.html
これで、git addが完了しました。
git commit
git commit(コミット)は、上記のgit addコマンドを用いてステージエリアに追加されたファイルやディレクトリのスナップショット(その時点のファイルの状態)をGitリポジトリに登録するためのコマンドです。
つまり、実際に変更を記録するためのコマンドとなります。
git commitのイメージ
git commitを実行する際には、「どのような変更内容か」を簡単なコメントとして残す必要があります。実際に、過去のコミットを確認するといった際に、コミット時のコメントを読むことで、ざっくりとそのコミットでどのような変更があったのかをすぐに把握することができます。
git commitコマンドを実行する際に、オプションの「-m」を付加することでコメントをつけることが可能です。
git commit -m "(コミットメッセージ)"
英語以外にも、以下のように日本語の文章をコミットメッセージに記載することももちろんOKです。
git commit -m "コミットテスト"
それでは、実際に先ほどgit addしたばかりのtest.htmlをgit commitしてみましょう。
git commitの実行結果
このように、無事にGitリポジトリにコミットし、変更内容を記録することができました。
おさらい
git addからgit commitまでの流れついて振り返ってみましょう。
ファイルは、以下の順番で移動していきます。
「ワークツリー」 → 「ステージエリア」 → 「リポジトリ」
このように、Gitでは、まずワークツリー内でファイルの変更作業を行い、ワークツリーのファイルをステージエリアに追加(git add)し、ステージエリアのスナップショット(その時点のファイルの状態)をリポジトリに記録(git commit)することでファイルのバージョン管理を行います。
この流れのイメージは非常に重要となりますので、しっかりとイメージを掴んでおきましょう。
作業内容をリポジトリへ記録するまでの流れのイメージ
git push
git push(プッシュ)は、ローカルリポジトリのブランチのコミット履歴を、リモートリポジトリに反映するためのコマンドです。
つまり、リモートリポジトリのコミット履歴をローカルリポジトリの最新の状態となるように更新することができます。git pullの逆を行なっているというイメージになります。
以下のように、指定したローカルリポジトリのブランチを、リモートリポジトリへpushすることができます。
git push (リモートリポジトリのアクセス先)(指定のブランチ名)
git pushのイメージ
ローカルリポジトリのmainブランチをリモートリポジトリへ反映したい場合は、以下のように実行します。
git push origin main
さて、さきほどローカルリポジトリ「test-remote-repositry」にてコミットを行なったことで、リモートリポジトリよりもコミット履歴の状態が進んでいます。git pushコマンドを実行し、ローカルリポジトリのtest.htmlをリモートリポジトリにも反映してみましょう。
git pushの実行結果
上記のように「〜〜〜100%(5/5), done」といった出力結果が表示されていれば、正常にpushが完了しています。
最後にGitHub上のリモートリポジトリにアクセスして、コミット履歴の状態を確認してみましょう。
リモートリポジトリでもローカルリポジトリで行なった最新のコミットが反映されているのが分かります。
index.htmlを開き、実際のコード内容も問題ないことが確認できました。これでgit pushが完了しました。
git tag
git tag(タグ)は、特定のコミットに対し、任意の名前を付けることができるコマンドです。「tag」という言葉の通り、分かりやすいようにタグ付けをするようなイメージとなります。
git tagの使いどころ
例えば、サービスリリース時などのキリが良いコミットに対し、目印をつけておく意味でgit tagを利用するといった使い道があります。
このように目的に応じて、任意のコミットに対し、分かりやすいタグを簡単に付与することができるのがgit tagのメリットです。
また、git tagには以下の2種類が存在します。
注釈付きタグ
注釈付きタグは、「タグ名」と「メッセージ」を付けることができます。2種類ある中で、注釈タグのほうが正式なタグでしっかりと情報が付けることのできるタグです。
以下のように記述し、実行することができます。
git tag -a (任意のタグ名) -m "(メッセージ)"
軽量タグ
軽量タグは、「タグ名」のみを付けることができます。上記のの注釈付きタグと比べて「メッセージ」の分の情報量を減らした省略形式のタグになります。
軽量タグは以下のように「任意のタグ名」のみ指定してコマンドを実行します。
git tag (任意のタグ名)
タグの使い分けについて
このように2種類のタグが存在しますが、基本的にはしっかりと情報量が付いた注釈付きタグの方を利用することをおすすめします。
それでは、試しにローカルリポジトリの最新のコミットにgit tagでタグを付けてみましょう。「tag_test」というタグ名で「注釈付きタグのテスト」というメッセージを付与してみます。
注釈付きタグの実行結果
コマンド実行後、エラーも特に返ってこなければOKです。
作成したタグ一覧の確認
また、以下のようにコマンドを実行することで、作成したtagを一覧で確認することができます。
git tag
実際に実行した結果、以下のように「tag_test」が出力されていることを確認できます。
git tagの実行結果
タグを削除する
不要になったタグは以下のように、-dオプションを指定し実行することで、タグの削除をすることが可能です。
git tag -d(削除したいタグ名)
さきほど作成したばかりの「tag_test」を削除してみます。
git tag -dの実行結果
上記のように「Deleted tag 〜〜〜」のような出力が表示されればタグの削除が完了しています。
念のため、直後に作成したタグの一覧を表示するgit tagコマンドを実行しています。先ほどまで出力されていた「tag_test」が表示されなくなっているため、無事問題なく削除することができました。
Lesson 3
Chapter 2
確認系のコマンド
チャプター1ではgit addやgit commitなどの情報や状態を更新する系の実践的なコマンドについて学んできました。このチャプターでは、更新系のコマンドによって記録された情報等を確認する系のコマンドについて学んでいきます。
git status
git status(ステータス)は、現在のディレクトリやファイルの変更状況を確認するためのコマンドです。以下のような内容を確認することができます。
-
ワークツリーとステージエリアの差分
-
ステージエリアとリポジトリの差分
変更状況を確認するには、以下のコマンドを実行します。
git status
①ワークツリーとステージエリアの差分を確認する
「前回ステージエリアに追加した後に変更したワークツリーのファイル」を確認するために利用します。git statusコマンドを実行すると、最新のワークツリーの状態と前回のステージエリアのスナップショットの状態を確認し、どのような差分があるかを出力します。
つまり、「ステージエリアに追加されていない変更がある」ということが分かります。該当のファイルをgit addすることにより、ワークツリーとステージエリアの状態を一致させることができます。
②ステージエリアとリポジトリの差分を確認する
「前回コミットしてからステージエリアに追加されたファイル」を確認するために利用します。git statusで最新のステージエリアと前回までのリポジトリの状態を知り、どのような差分があるかを出力します。
つまり、「ステージエリアに追加済みであるけれどもまだコミットしていない変更がある」ということがわかるので、git commitすることにより、ステージエリアとリポジトリの状態を一致させることができます。
実際のコードで試してみましょう。以下のようにtest.htmlの5行目に「git status」と記述しています。
git statusを実行します。すると、以下のような出力がされます。
git statusの実行結果
「Changes not staged for commit」や「modified: test.html」というメッセージが出力されています。
ワークツリー内の「test.html」というファイルが「まだステージエリアに追加(add)されていない状態」ということを伝えています。つまり、①の状態にいます。
ステージエリアに追加する必要があるので、続けてgit addを行なったのちに、再度git statusコマンドを実行します。
git add後のgit statusの実行結果
すると、出力結果が変わっています。「Changes to be committed」というメッセージに変わり、「modified: test.html」の色が緑色になりました。
ワークツリー内の「test.html」というファイルが「ステージエリアに追加(add)された状態」となったが、「まだコミットされていない変更」ということを伝えています。つまり、②の状態です。
最後に、git commitを実行し、再度git statusで確認します。
git commit後のgit statusの実行結果
すると、また出力結果が変わりました。「nothing to commit, working tree clean」というメッセージは「コミットすべき変更は何も無い」という状況を伝えています。すなわち、ワークツリーとステージエリア、リポジトリの変更内容がすべて一致している状態となります。
git statusで確認する癖を付けよう
実際の開発現場では、作業の内容によっては一度に複数のディレクトリやファイルに対して編集を行うこともあります。
ちょっとしたミスで変更すべきファイルをコミットし忘れるなどといったヒューマンエラーにより予期せぬバグを発生させてしまう恐れを限りなくゼロにするためにも、作業中のファイルの状態を正しく把握しておくことが重要です。
そのためにもコミットやステージエリアに追加する前には、どのファイルが変更されたかを一度git statusによって確認する癖を付けることをおすすめします。
git branch
git branch(ブランチ)は、ブランチの作成、一覧表示などを行うためのコマンドです。
ブランチの説明については、Lesson3 チャプター1の「git checkout」の項目にて触れましたが、おさらいすると、「枝分かれした、それぞれの作業内容の履歴」のことです。(詳しくは上記の項目をご覧ください。)
ブランチの作成
ブランチを新規作成するには、git branchの後に任意のブランチ名を記載して実行します。
git branch (任意のブランチ名)
それでは、ローカルリポジトリ「test-remote-repositry」に対し、ブランチを作成してみます。現在リポジトリには「main」ブランチしか存在しませんので、開発用という名目でdevelopmentブランチを作成してみたいと思います。
以下のようにコマンドを実行します。
git branch developmentの実行結果
特にエラーが出ていなければこれでdevelopmentブランチの作成は完了です。
作成したブランチ一覧の確認
引数を何も指定せずにコマンドを実行することで、作成したブランチを一覧で確認することができます。
git branch
さきほど、作成したばかりのdevelopmentブランチも表示されるか確認してみましょう。
git branchの実行結果
問題なくmainブランチとdevelopmentブランチが存在していることが確認できました。
また、*マークが付いて緑色になっているブランチは現在チェックアウトしているブランチとなります。
勘違いしやすいポイントとして、作成したブランチに自動でチェックアウトされると思いがちですが、そうではありません。「mainブランチにいる状態でdevelopmentブランチを作成した」だけであり、あくまでも現在チェックアウトしているブランチはmainブランチになります。
developmentブランチに移動する場合には、git checkoutコマンドを用いて、mainブランチからdevelopmentブランチに移動(チェックアウト)をする必要があります。
また、今回mainブランチにいる状態でdevelopmentブランチを作成しましたが、developmentブランチにチェックアウト後のファイルの状態を確認してみましょう。
まずは、以下のようにdevelopmentブランチにチェックアウトします。
developmentブランチにチェックアウトしていることが確認できたため、続いて、test.htmlの内容を確認します。
ファイルの内容はmainブランチのtest.htmlの内容と同じになっています。その理由は、developmentブランチはmainブランチから派生して作成されたため、現時点ではdevelopmentブランチが見ているコミット履歴はmainブランチと一致しているためです。
そのため、ファイルの内容はmainブランチと同じ状態となります。
mainブランチとdevelopmentブランチのコミット履歴は一致する
その他の機能
git branchには他にもいくつか便利な機能が存在するコマンドです。
例えば、「ブランチの削除」や、「ブランチ名の変更」といった操作を実行することができます。
「ブランチの削除」や、「ブランチ名の変更」について
この2つの操作についてはチャプター3の「リカバリ系のコマンド」にて詳しく説明します。
git log
git log(ログ)は、コミットの履歴(ログ)を表示するためのコマンドです。
過去にどういった変更を加えたかなどを確認する際に活用することができます。特にオプションを指定しなければ、コミット履歴はコミットの新しい順に表示されます。
表示される内容は上から順に下記の項目です。
-
コミットのID(ハッシュ値)
-
コミットしたユーザの氏名、メールアドレス
-
コミットした際の日にちや時刻
-
コミットメッセージ
コミットの履歴を確認するには、以下のコマンドを実行します。
git log
それでは、ローカルリポジトリ「test-remote-repositry」に対し、git logコマンドを実行してみます。
git logの実行結果
このように、コミットをした際の情報が表示されます。
Lesson2の「git config(認証情報)」の項目でも触れましたが、そこで設定した「ユーザ名」と「メールアドレス」がここで表示されます。
誰がいつどのようなコミットを行なったかをgit logコマンドを用いることですべて確認することができるため、実際の開発作業においても、過去のコミット内容を確認したい場合によく活用することになります。
Lesson 3
Chapter 3
リカバリ系のコマンド
チャプター2ではgit statusやgit logなどの状態を確認する系のコマンドについて学んできました。
このチャプターでは、直前の操作の取り消しや、一度記録された状態を別の状態へと変更したりといったリカバリ系のコマンドについて学んでいきます。
git addの取消 (git reset)
git reset(リセット)は、git addでステージエリアに追加した内容を取り消しするためのコマンドです。reset(リセット)の言葉の通り、「今の状態を取り消して、改めてやり直す」というイメージです。
この時、指定した変更がステージエリアから取り消されるのみであるため、ワークツリーのファイルには影響がありません。
ただ、実際には、git resetを実行時に裏側では「リポジトリから最新のコミットの情報を取得し、ステージエリアの内容を上書きする」という処理が行われています。
git reset実行時の処理
git resetは以下のようにコマンドを実行します。
HEADとは、いま自分がチェックアウトしているブランチの最新のコミットのことです。
つまり、引数にHEADを指定することで、最新のコミットの情報を取得し、ステージエリアの指定したファイルの状態をコミットの状態と同じになるように上書きすることで「git addの取り消し」をしています。
git reset HEAD (ファイル名 or ディレクトリ名)
では、実際のコードで試してみましょう。
以下のようにtest.htmlに対し、適当な文章を追加します。ここでは、7行目に「git resetを実行したいメッセージです」と記述しています。
この状態で、git addコマンドを実行します。
git add test.html
これで、上記の編集内容がステージエリアへ追加されました。
続いて、git resetコマンドを実行して、直前のgit addを取り消しします。
git resetの実行結果
合間にgit statusコマンドを挟みながら、git resetコマンドの実行までを行いました。git addコマンド直後のgit statusコマンドでは、test.htmlがステージエリアまで追加されていますが、git resetコマンド直後のgit statusコマンドでは、test.htmlがまだステージエリアに追加されていない、という出力がなされていることが確認できます。
また、この時、ワークツリーのtest.htmlの編集内容自体には影響が無いため、7行目の「git resetを実行したいメッセージです」という記述はこのままとなります。
これで、無事にgit addの取消を行うことができました。
修正ソースの退避 (git stash)
git stash(スタッシュ)は、ワークツリーにて現在作業中の内容をstashという場所へ一時的に避難させることができるコマンドです。「stash」は英語で、「避難場所」、「隠す」、「こっそりしまう」といった意味があります。
使いどころとしては、現在自分がチェックアウトしているブランチにて、作業内容が途中でまだコミットしたくない状態で、別のブランチで作業しないといけなくなった場合に使用します。
というのも、まだコミットされていないワークツリーの変更がある際に、別のブランチにチェックアウトすることはGitの仕様上不可能です。そのため、別のブランチにチェックアウトをするためには、現在のブランチにてワークツリーの状態とリポジトリの状態が一致している状態にする必要があります。
そこで、git stashを実行し、専用に用意された避難場所(stash)に作業中の内容を一時保管してから、別ブランチに移動し、別ブランチでの作業完了後、元のブランチに戻り、stashに一時保管しておいた内容を取り出すことで、当時の作業中の内容でワークツリーを更新することができます。
git stashコマンドは以下のように実行します。
git stash
一時避難した作業一覧の確認
作業内容の一時避難は何回でも可能なため、複数のstashが蓄積することがあります。
そんな場合など、stashの一覧を確認するためには、以下のコマンドを実行します。
git stash list
一時避難した作業の復元
一時避難した作業内容を再度ワークツリー側に復元(反映)させるには以下のコマンドを実行します。
git stash apply
一時避難した作業の削除
stash内にある最新の作業を削除するには、以下のコマンドを実行します。
git stash drop
特定の作業を削除するには、以下のようなコマンドを実行します。({}内の数字は最新の作業を0として古い作業になるたびに1ずつ増えていきます。つまり、以下の実行例の場合は、2番目に保管されている作業を削除するという意味になります。)
git stash drop stash@{1}
すべての作業を削除したい場合には、以下のコマンドを実行します。
git stash clear
では、一連の流れを実際のコードで試してみましょう。
以下のようにtest.htmlに対し、7行目の「git resetを実行したいメッセージです」という記述を「git stashを実行したいメッセージです」に変更します。
この状態で、別ブランチに移動しなければならない状況が出来たと仮定し、git stashを活用していきます。
git stashの実行結果
このように、ワークツリーの内容を作業前の状態に戻すことができました。
続いて、stashに避難した作業が保管されているか確認してみましょう。
git stash listの実行結果
stashにも避難した作業が保管されていることを確認できました。
ここで、別ブランチでの作業が完了したと仮定し、stashにある作業を現在のブランチに復元していきたいと思います。
git stash applyの実行結果
上記のように、stashにある作業をワークツリーに復元することができました。
ちなみに、git stash applyをしてもstash内に当該作業情報が保管されたままとなります。復元が完了して、不要になった作業はstashから削除してしまいましょう。
git stash dropの実行結果
最新の作業を削除すれば良いので、git stash dropコマンドを実行しました。直後のgit stash listコマンドにて出力結果が何も表示されなくなっているので、無事に作業の削除ができたことを確認できました。
このように、git stashは、まだコミットはしたくないが、現在の作業を捨てたくない場合に役立ちます。ぜひ使いこなせるようにしておきましょう。
修正ソースの破棄 (git checkout .)
git checkout . コマンドは、ワークツリー内の編集作業をすべてなかったことにしたい、つまり、作業内容の破棄をしたい場合に利用します。
ワークツリー内の変更が破棄されるのみとなるため、ステージエリアとリポジトリに対して影響はありません。内部的には、ワークツリーの状態をステージエリアの状態と同じ状態にするという処理が起こっています。
git checkout . 実行時の処理
注意
チャプター1「更新系のコマンド」で学んだgit checkoutコマンドではブランチを移動するために用いていましたが、引数が「ブランチ名」ではなく「.(ピリオド)」の場合は、「現在のワークツリー内の変更を取り消す」という意味になりますので、間違えないように気を付けてください。
以下のコマンドを実行します。
git checkout .
実際のコードで試してみましょう。
以下のようにtest.htmlに対し、適当な文章を記述します。ここでは、7行目に「作業内容を破棄したいメッセージです」と記述しています。
この状態で、git checkout .を実行します。
git checkout .の実行結果
すると、ほかの内容は無事のまま、さきほど記述した文章のみが表示されなくなっていることが確認できます。
このように、ワークツリー内のファイルを作業が発生する前の状態まで戻すことができました。
また、特定のファイルのみ元に戻したい場合は、引数にファイル名を指定して実行します。
git checkout (ファイル名)
例えば、ワークツリー内に編集中のファイルが複数存在する状態で、test.htmlのみ元に戻したい場合は以下のようにコマンド実行すればOKです。
git checkout test.html
このように、git checkout .コマンドは、実際の開発現場でも活用される便利なコマンドであるため、ぜひ覚えておきましょう。
特定のコミットを破棄 (git revert)
git revert(リバート)は、特定のコミットを取り消したい場合に利用するコマンドです。「revert」は英語で「元に戻す」、「立ち戻る」といった意味があります。
仕組みとしては、「取り消ししたいコミットを打ち消すための新しいコミットを追加する」という形になります。真逆の内容のコミットを追加することで指定した既存のコミットの内容が打ち消される形になります。
以下のイメージ図のように、「コミット3」を取り消すために、「コミット3」とは真逆の内容で「コミット3'」を追加します。
git revertのイメージ
注意
git revertは、あくまでも特定のコミットを打ち消すための新しいコミットを行っているだけなので、取り消したいコミット自体が履歴から無くなるわけではありません。
git revertを行うには、以下のように取り消ししたいコミットIDを指定し、コマンドを実行します。
git revert (コミットID)
実際のコードで試してみましょう。
以下のようにtest.htmlに対し、適当な文章を記述します。ここでは、7行目に「git revert用のメッセージです」と記述しています。
続けて、git add、git commitを実行し、ローカルリポジトリにコミットを記録します。
コミット完了までの実行結果
ここで、例えば、コミット後に作業内容に誤りがあったと発覚し、コミットの内容を無かったことにしたいというケースが発生したと仮定します。ここで、git revertを行い、たったいま記録したコミットを打ち消すように対応します。git revertを実行するには、どのコミットに対してかを指定するため、コミットIDを知る必要があります。
そこで、まずはgit logコマンドを実行し、過去のコミット履歴の中から打ち消し対象のコミットを見つけましょう。
git logの実行結果
今回はコミットメッセージが「git revert用のメッセージです」である最新のコミットが打ち消し対象のコミットですので、コミットIDが「d47be161ba3c1fa460f702dc3e494f1bfda842c1」だと確認ができました。
このコミットIDを指定してgit revertを実行します。
git revertのコミットメッセージ入力画面
すると、このようにコミットメッセージの入力画面が立ち上がります。
「Revert "git revert用のメッセージを追加"」という部分がデフォルトで提案されるコミットメッセージとなります。今回はメッセージに変更を加えず、「:wq」を入力し、Enterキー押下でこの画面を終了します。
git revertの実行結果
画面を終了すると、上記のようにgit revertが完了し、新しいコミットが追加されました。git logコマンドを実行し、最新のコミットにgit revertによって追加されたコミットが確認できます。
最後にワークツリーの内容も確認します。
git revertのコミットメッセージ入力画面
7行目に「git revert用のメッセージです」と記述した作業のコミットがgit revertによって打ち消され、無かったことになっています。
このように、特定のコミットを破棄する際に、git revertは役立ちます。
特定のコミットを取込 (git cherry-pick)
git cherry-pick(チェリーピック)は、特定のコミットの内容を現在のブランチに追加することができるコマンドです。「cherry-pick」は英語で、「自分の気に入ったものだけをつまみ食いする」、「いいとこ取り」といったニュアンスの意味を持ちます。
現在チェックアウトしているブランチに、別のブランチで複数コミットされている内容の中から一部のコミットだけ取り込みたいが、すべてのコミットを取り込みたくない場合などに活用することができます。
git cherry-pickのイメージ
git cherry-pickを行うには、以下のように取り込みたいコミットIDを指定します。
git cherry-pick (コミットID)
実際のコードで試してみましょう。
今回は、mainブランチに対し、developmenmtブランチの複数コミット履歴の中からとある1つのコミットをcherry-pickし、mainブランチに取り込んでみたいと思います。
事前準備として、mainブランチに存在しないコミットをdevelopmentブランチで作成しておく必要がありますので、新しいコミットを2つ追加しておきたいと思います。
developmentブランチにチェックアウトし、以下のように、7行目に「git cherry-pick用のコミット1です」と記述しています。
上記の作業内容でコミットまでを行います。続いて、9行目に「git cherry-pick用のコミット2です」と記述し、同様にコミットを実行します。
developmentブランチに移動し、上記の2つのコミットを記録し、git logでコミット履歴の確認までの流れが以下になります。
実行結果
最新の2件のコミットは、developmentブランチで実行したコミットのため、mainブランチには当然これらのコミットは追加されていません。
ここで、developmentブランチの最新から2個目コミット(「git cherry-pick用のコミット1」のメッセージのコミット)をmainブランチに取り込みたいと仮定します。
そこで、まずは、mainブランチにチェックアウトし、続けてgit cherry-pickを実行します。
git cherry-pickの実行結果
問題なくgit cherry-pickが完了しました。実際のtest.htmlの内容も確認してみましょう。
こちらも期待通りに指定したコミットのみをmainブランチのtest.htmlに反映することができました。
git cherry-pickはいざという時に役に立つコマンドですので、しっかりと覚えておきましょう。
直前のコミットメッセージの修正 (git commit --amend)
git commit --amend(アメンド)は、コミットの際に記述するコミットメッセージの内容を修正したい場合に使用します。「amend」は英語で、「修正する」、「改正する」という意味です。
コマンドは以下のように実行します。
git commit --amend -m (修正後のコミットメッセージ)
実際のコードで試してみましょう。
mainブランチのtest.htmlに適当な文章を追加します。ここでは、9行目に「git commit --amend用のメッセージです」と記述しています。
続いて、git addし、以下のようなコミットメッセージでコミットまでを行いました。
実行結果
しかし、コミットメッセージをよく見ると、「メッセージ」と入力するつもりが「メッセーji」とタイプミスしたことに気づかずにコミットを実行してしまったことが判明しました。
このように、直前のコミットのメッセージを修正する際に、git commit --amendを活用します。
git commit --amendの実行結果
このように、メッセージの修正を実行しました。git logコマンドを実行し、最新のコミットのメッセージが期待通りに修正されていることも確認することができました。
注意
直前(最新)のコミットのコミットメッセージを修正するためのコマンドであり、2つ以上前のコミットは修正できませんので、注意が必要です。
ブランチの削除 (git branch -D)
ブランチの削除をするには、git branchコマンドにオプションで「-D」をつけて実行します。「D」は「delete」の略です。
git branch -D (削除したいブランチ名)
例えば、ローカルリポジトリ内のdevelopmentブランチを削除する場合、以下のようにコマンドを実行します。
git branch -D development
注意
Gitでは現在のブランチを削除することはできないため、削除したいブランチ以外のブランチに切り替え(git checkout)を行ってから、対象のブランチの削除を実行します。
実際のコードでも試してみましょう。
開発用に作成していたdevelopmentブランチを削除してみたいと思います。まず、削除対象以外のブランチに移動する必要があるため、mainブランチにいる状態で、developmentブランチの削除を実行します。
git branch -Dの実行結果
無事にdevelopmentブランチの削除が完了したことが確認できました。
不要なブランチはなるべく削除し、管理しやすい状態を保つように心がけましょう。
コミットログをきれいにする(複数コミットを一つにまとめる) (git rebase -i)
開発作業を進める中で、コミット履歴内のいくつかのコミットを1つのコミットにまとめたいという状況が出てきたとします。
そんな場合に、git rebase -i というコマンドを活用することができます。「rebase」は「リベース」と読み、「re + base」つまり、根元を「付け替える」、「植え替える」といったニュアンスがあります。
オプションの「-i」は「interactive」の略です。オプション「-i」が付くことによって、「対話的リベース」といい、画面とやり取りをしながら該当のコミット履歴の変更操作を行います。
git rebase -i によるコミットをまとめるイメージ
rebaseの操作は少々複雑ですので、実際のコードにて試してみましょう。
mainブランチのtest.htmlの11行目に「git rebase用のメッセージ1です」と記述しています。
この編集内容で一度コミットします。続けて、12行目に「git rebase用のメッセージ2です」と記述し、2つ目のコミットを実行します。
実行結果
ここで、上記の2つのコミットですが、変更内容がそれぞれ似ているため、コミットログを綺麗にするために、1つのコミットにまとめてみたいと思います。
そこで、以下のコマンドを実行します。
git rebase -i HEAD~2
上記の実行コマンドでは、引数に「HEAD~2」と記述しています。つまり、「コミット履歴内の最新の2つ分のコミットがリベースの対象になる」ということになります。
実際にコマンドを実行すると、以下のエディタが立ち上がります。
git rebase -i HEAD~2の実行直後に立ち上がるエディタ
画面の最上部にリベース対象のコミットが表示されています。
注意
表示される対象コミットは古い順に上から下に表示されます。最新のコミット順に表示されるgit logコマンドとは逆になりますので、注意してください。
ここで、2個目のコミットを1個目のコミットに統合して1つにまとめたいと思います。
キーボードから「i」キーを押下し、入力モードに切り替えてから、2個目のコミットの左端に表示されている「pick」を「squash」と変更してください。
「squash」を指定するとそのコミットを直前のコミットとひとつにすることができます。(「squash」は「押しつぶす」、「ぺちゃんこにする」という意味があります。)
例えば、今回は一番古いコミットを「pick」のままにし、もう片方のコミットを「squash」とすることで、この2つのコミットを1つにまとめることができます。
「:wq」を入力し、Enterキー押下でこの画面を終了します。
直後に立ち上がるエディタ
すると、再度別のエディタが立ち上がります。この画面はこのまま保存して終了します。
以下のように、git rebaseの処理が完了した状態になりました。
git rebase完了後
最後に、git logコマンドを実行し、コミット履歴の確認および、test.htmlの内容を確認しておきましょう。
git logの実行結果
最新の2つのコミットが1つにまとまり、編集した内容も元々2つのコミットで記録した内容となっているため、正しくgit rebase -iコマンドを実行できたことが確認できました。
git rebaseは慣れるまでには少し時間がかかるかもしれませんが、使いこなせれば、ログを綺麗に保つことができる非常に便利な機能であるため、ぜひ使えるようにしましょう。
ブランチ名を変更する(git branch -m)
ローカルリポジトリ内のブランチ名を変更するにはgit branch -mコマンドを使用します。「m」は「move」の略です。ブランチ名を間違って作成してしまった場合の変更等に活用することができます。
git branch -m (現在のブランチ名) (新しいブランチ名)
実際のコードで試してみましょう。
現在、ローカルリポジトリ(test-remote-repositry)には、mainブランチしか存在しないため、再度新たにdevelopmentブランチを作成したいと思います。ただ、作成する際に、スペルミスをした状態で作成をしてみます。
git branch developmensの実行結果
上記で、スペルを間違えてdevelopmensというブランチを作成してしまった状態です。
この際に、git branch -mを用いて「developments」を「development」へ変更します。
git branch -mの実行結果
これで、ブランチ名の変更をすることができました。
また、現在開いているブランチの名前を変更したい場合は、引数の「現在のブランチ名」を省略することが可能です。
git branch -m (新しいブランチ名)

