Gitの基本概念と最低限覚えておくべきコマンド

バージョン管理ツールのGitは、システム開発の現場でよく使われています。

しかし、”システムエンジニアであれば使えて当たり前”というような扱いになっていることもあり、なかなか現場で一から学習するのは難しいのではないでしょうか。

この記事では、Gitを使った経験があまりない方向けに、基本的な仕組みと最低限必要なコマンドについて解説します。

目次

Gitの基本概念

まずは、Gitの基本的な仕組みを見ていきましょう。

プロジェクトとは何か

Gitではひとつのまとまったファイル群を「プロジェクト」という単位で管理します。

「プロジェクト」は、多くの場合ひとつのディレクトリ、および、その配下にあるサブディレクトリを指すことになります。

例えば、Windows環境においてCドライブ直下に「Sample」という名前のフォルダを作り、これをプロジェクトとして管理することに決めたとしましょう。

このとき、「Sample」フォルダの中にa.txtというファイルを作成し、その後に更新する場合を考えてみます。

つまり、

  1. a.txtを作成
  2. a.txtの内容を編集

という順序で作業していくということです。

これらの作業はどちらも「Sample」フォルダ内で行われているため、「Sample」というひとつのプロジェクトに記録されることになります。

一方で、「Sample」と同じ階層に「Sample2」という別のフォルダを作成し、こちらを新たにプロジェクトとして管理することにしたとしましょう。

「Sample2」フォルダ内でb.txtというファイルを作成したとしても、その作業内容は「Sample」のプロジェクトには記録されません。これは、「Sample2」が「Sample」の外側にあり、別のプロジェクトとして管理されているためです。

このように、同一のプロジェクトに対する操作はすべて一連の記録として残りますが、別のプロジェクトに対する操作は記録されないということになります。

Gitにおける4つの作業領域について

Gitでは、プロジェクトごとに、以下の4つの作業領域を用いてバージョン管理が行われています。

  1. ワークツリー
  2. ステージ
  3. ローカル・リポジトリ
  4. リモート・リポジトリ

1のワークツリーから3のローカル・リポジトリまでは、個々の開発者のコンピュータ上に存在する領域です。

一方、4のリモート・リポジトリは、インターネットやLANなど、ネットワーク上のサーバーに存在する領域です。こちらは、ワークツリーやローカル・リポジトリとは異なり、複数の開発者から参照される領域になります。

ファイルの作成や変更などの作業は、まずはワークツリーからローカル・リポジトリまでの領域で行われ、その後リモート・リポジトリに送信されることで、複数の開発者で共有できる形で記録されることになります。

Gitのコマンドの機能・役割を理解するためには、4つの領域がそれぞれどのようなものなのか、そして、相互にどう関係しているのかを理解することが必要です。

以降で、ワークツリーからリモート・リポジトリまで、ひとつひとつがどのような役割のものなのかを見ていきましょう。

1. ワークツリー

ワークツリーとは、Gitにおいて実際にファイルの編集を行う作業領域のことです。ここでファイルの編集、追加、削除などを行います。

Gitを使用していなくても、ファイルの編集などの作業を行うことがあると思いますが、そのような作業を行っている領域のことをGitではワークツリーと呼ぶ、ということです。

ワークツリーでの変更を記録するためには、ステージへの追加、ローカル・リポジトリへのコミットなどを明示的に行う必要があります。

2. ステージ

ステージは、次のコミット(ローカル・リポジトリへの記録)に含めたい変更を一時的に保管しておくための領域です。

ワークツリーでファイルを編集した後、その変更をステージに追加します。これは、Gitに対して次のコミットに含めるべき内容を指定するために行います。変更をステージに追加する操作を「ステージング」と呼びます。

Gitでは、通常、ワークツリーから直接ローカル・リポジトリへコミットすることはありません。

なぜかというと、複数のファイルを編集した後に、そのうちの一部の変更だけをコミットする必要がある場合、ステージが存在しないと、間違ったファイルをコミットしてしまうリスクが高まるからです。

ステージを使うことで、コミットする前に変更内容をもう一度見直して、必要なら修正を加えることもできます。ステージに追加した変更は、コミットするまでは取り消せるので、じっくりとレビューしてから最終的にコミットすることができるということです。

3. ローカル・リポジトリ

ローカル・リポジトリとは、個々の開発者のコンピュータ上に存在するファイルの更新履歴を記録している領域です。

ローカル・リポジトリは、あくまで開発者の個人的な環境に存在するため、他のユーザーから直接参照されることはありません。

しかし、ファイルの更新日時や変更理由など、バージョン管理に必要な情報はリモート・リポジトリ(他の開発者と共有するサーバ上のリポジトリ)と同様に記録されます。

ローカル・リポジトリに記録された情報は、リモート・リポジトリにプッシュ(アップロード)することができます。

4.リモート・リポジトリ

リモート・リポジトリは、ネットワーク上に存在するGitのリポジトリです。

複数の開発者が協力して開発をする際は、リモート・リポジトリを使用してプログラムなどの資源を共有することになります。

ローカル・リポジトリに記録された変更内容をリモート・リポジトリにプッシュ(アップロード)したり、あるいは、リモート・リポジトリの内容をプル(ダウンロード)して、ローカル・リポジトリの内容を最新化したりすることができます。

また、既存のプロジェクトに対して新たな開発者が参加する場合は、まずは、リモート・リポジトリからプロジェクトの情報をダウンロードすることから始まります。

Gitの基本コマンド

ここからは、Gitで使用する基本的なコマンドを見ていきましょう。

【git init】Gitプロジェクトを新規作成する

新規のGitプロジェクトはgit initコマンドを使用して作成します。

作成手順は以下のようになります。

  1. プロジェクト用のディレクトリへ移動する。
  2. git initコマンドを実行する。

これで、対象のディレクトリがgitのプロジェクトとして認識されます。

なお、コマンドが正しく完了すると、プロジェクトディレクトリの直下に、隠しディレクトリの「.git」が作成されます。

「.git」はプロジェクトに関する情報を格納するためのディレクトリで、ステージやローカル・リポジトリの内容もここに含まれます。

「.git」の中には設定ファイル等も格納されており、不用意に編集してしまうと、プロジェクト自体が破損してしまう可能性があります。

何かトラブルがあって状況を確認するために参照するのは問題ありませんが、「.git」の中身を直接編集することは極力避けるようにしましょう。

変更内容を記録するコマンド

ワークツリーで行った変更は、まずステージに追加し、その後ローカル・リポジトリにコミットすることでgitのバージョン管理に載せることができます。

ここでは、ステージへの追加、ローカル・リポジトリへのコミットに使用するコマンドを見ていきましょう。

【git add】ワークツリーの変更をステージに追加する

ワークツリーの変更をステージに追加するには、git addコマンドを使用します。

構文は以下の通りです。

コマンド:git add <ファイル名|ディレクトリ名|.>

※<ファイル名|ディレクトリ名|.>は、ファイル名、ディレクトリ名、「.」(ピリオド)のいずれかが入るという意味です。

例)

  • git add a.txt:a.txtをステージに追加する
  • git add sample:sampleという名前のディレクトリ(または、ファイル)をステージに追加する。
  • git add .:ワークツリーで行われたすべての変更をステージに追加する。

【git commit】ステージに追加された変更をローカル・リポジトリにコミットする

ステージに追加された内容をローカル・リポジトリに登録するには、git commitコマンドを使用します。

コマンド:git commit

git commitコマンドを使用すると、テキストエディタが起動されます。起動したテキストエディタには、コミットコメント(コミットの内容を説明するための文章)を入力することができます。コミットコメント入力後に、上書き保存を行ってからエディタを閉じることでコミットが完了します。

コミットを行うことで、ステージに追加されていた変更内容がローカル・リポジトリへと記録されます。

なお、コミットの際には、ファイル名やディレクトリ名などを指定する必要はありません。記録する対象は、ステージへ登録することですでに選ばれているためです。

変更内容を確認するコマンド

git addgit commitの両コマンドを使用することで、ローカル・リポジトリへコミットすることができます。

しかし、上記のコマンドだけだと、ワークツリーにあるファイルの中で何がコミット済みで、何がコミットされていないのか、あるいは、ステージへ反映されている変更が何なのかがわからなくなる可能性があります。

そこで、ステージやローカル・リポジトリへの反映状況を確認するコマンドを紹介します。

【git status】どのファイルがコミットされていないかを確認する

ワークツリーにあるファイルの中で、ステージやローカル・リポジトリへ反映されていないものがどれなのかを確認するには、git statusコマンドを使用します。

コマンド:git status

git statusコマンドを使用すると、ワークツリー上で変更されたファイルのうち、ステージやローカル・リポジトリへ反映されていないものを表示することができます。

git statusコマンドを実行した結果どのように表示されるのか、いくつかの例を見ていきましょう。

ワークツリー上で何も変更されていない場合

nothing to commit, working tree clean

コミットすべきファイルはなく、ワークツリーがキレイな状態であると表示されています。

ワークツリー上で変更されているが、ステージへ追加されていない場合

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   after.txt
	deleted:    first.html

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	a.txt

no changes added to commit (use "git add" and/or "git commit -a")

Changes not staged for commitで始まる段落と、Untracked filesで始まる段落があります。

Changes not staged for commitで始まる段落には、内容が修正されたファイルと、削除されたファイルが表示されます。

modified: after.txtの部分が、after.txtというファイルが修正されたことを表しています。また、deleted: first.htmlという部分が、first.htmlというファイルが削除されたことを表しています。

Untracked filesには、新規で追加されたファイルが表示されています。

Untrackedというのはgitの管理下に入っていないことを意味しています。新規に追加されたファイルは、まだgitでバージョンが管理されていないので、このような表示になります。

ステージへ追加されているが、ローカル・リポジトリへコミットされていない場合

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   after.txt

Changes to be commitedは、コミットすべき変更があることを表しています。上記の例で言えば、after.txtというファイルの変更がステージに反映されているので、それがコミット対象として表示されているということです。

git statusコマンドを実行したときに表示されるメッセージには、ワークツリーやステージの状況が表示されます。また、それと同時に、次に行うべき作業で使用するコマンドがカッコの中に表示されています。

つまり、git statusコマンドを実行すると、現在の状況だけでなく次に実行すべきコマンドも確認できるということです。ですので、慣れないうちは、コマンドを実行するたびに、git statusコマンドで現状と次のコマンドを確認しながら作業を進めるのが良いでしょう。

【git log】ローカル・リポジトリの履歴を確認する

ローカル・リポジトリの履歴を確認するには、git logコマンドを使用します。

コマンド:git log

git logコマンドを使用すると、各コミットごとにコミットしたユーザー、コミット日時、コメントなどの情報が表示されます。

最新のコミット履歴から過去に遡っていく順で表示され、Enterキーを押下することで、一番最初のコミット履歴まで表示されていきます。

途中で履歴の表示を止めるには、アルファベットの「q」を押します。

git logコマンドを普通に実行した場合、1コミットあたり短くても6行のログが表示されます。ですので、数十、数百といったコミットがされている場合には、大量のログが表示されることになり、自分が見たいログが見つけづらくなることがあります。

そこで、git logコマンドの結果を見やすくするためのオプションをいくつか紹介します。

コマンド:git log -n <コミット数>

-nオプションとコミット数を指定することで、指定した件数分のコミットログを表示することができます。最新の3世代分や5世代分を見たいといったように、直近の数世代のログを確認する場合に便利な方法です。

コマンド:git log -p <ファイル名>

-pオプションとファイル名を指定することで、指定したファイルのコミット履歴だけに絞って表示することができます。履歴を確認したいファイルが1つの場合に有用な方法です。

コマンド:git log --oneline

--onelineオプションをつけると、1コミットあたりのログを1行だけに絞ることができます。この場合、コミットユーザーや日時は表示されず、各コミットのコメントだけが表示されるようになります。

【git diff】コミットされたファイルの変更内容を確認する

どのファイルが変更されているかだけでなく、変更内容も合わせて確認するにはgit diffコマンドを使用します。

コマンド:git diff

git diffコマンドを実行すると、その時点でのワークツリーとステージの内容を比較することができます。

ワークツリーでファイルを変更し、まだステージに反映されていない場合に、その差分が表示されるということです。

ワークツリーでの変更をステージに反映すると、ワークツリーとステージの差分がなくなるため、git diffコマンドの表示対象からは外れます。

ただし、--stagedオプションをつけると、ステージとローカル・リポジトリのファイルを比較することができます。

コマンド:git diff --staged

この場合、ステージに変更が反映されており、それがコミットされていない時に、差分が表示されることになります。

変更を取り消すコマンド

ワークツリーやステージで行われた変更は、コミット前であれば取り消すことができます。

必要なコマンドはgit statusコマンドを実行すると表示されるのですが、実行した時にどのような動きをするのかを具体的に見ていきましょう。

【git restore】ワークツリーの変更を取り消す

ワークツリー上での変更を取り消すためには、以下のコマンドを実行します。

コマンド:git restore <ファイル名|ディレクトリ名>

git restoreコマンドを実行すると、指定されたファイルまたはディレクトリについて、ワークツリー上の変更が取り消されます。取り消された変更は、直前のコミット時点の状態に戻ります。

git restoreコマンドで取り消された変更は完全に失われます。ですので、取り消す前に、変更内容を確認しておくと良いでしょう。

【git restore --staged】ステージに反映された変更を取り消す

ステージ上の変更を取り消すには、以下のコマンドを実行します。

コマンド:git restore --staged <ファイル名|ディレクトリ名>

こちらは、ステージ上の変更内容だけを取り消します。ワークツリーの内容は変更されません。ワークツリーの変更も取り消したい場合には、続けてgit restoreコマンドを実行しましょう。

特殊な変更方法

ファイル名の変更やファイルの削除を行う場合、gitでは専用のコマンドを使用することができます。

【git mv】ファイルを移動する

ファイル名を変更、または、ファイルを移動する場合、git mvコマンドを使用します。

コマンド:git mv <旧ファイル名> <新ファイル名>

コマンド:git mv <移動元> <移動先>

git mvコマンドを使用すると、ワークツリー上でファイル名が変更(または、ファイルが移動)され、その内容がステージに反映されます。

よって、直後にgit commitコマンドを実行すれば、そのままローカル・リポジトリへ反映することができます。

【git rm】ファイルを削除する

ファイルを削除するには、git rmコマンドを使用します。

コマンド:git rm <ファイル名>

git rmコマンドを実行すると、ワークツリー上で指定されたファイルが削除され、その内容がステージにも反映されます。

続けてgit commitコマンドを実行すれば、そのままローカル・リポジトリにコミットすることができます。

削除対象がディレクトリの場合は、-rオプションを指定します。

コマンド:git rm -r <ディレクトリ名>

-rオプションを使用すると、指定したディレクトリとその配下にある全てのファイルが削除されます。

--cachedオプションを指定すると、ステージ上のみでファイルを削除し、ワークツリー上のファイルは残すことができます。

コマンド:git rm --cached <ファイル名>

ブランチ

通常、何らかの変更をリポジトリにコミットすると、新たなバージョンがひとつ作られます。このとき、元になったバージョン側から見ると、それを元にして作られた新たなバージョンはひとつしかないことになります。

たとえば、バージョン1を元に何かを変更して、バージョン2が作られたとしましょう。このとき、バージョン1から見ると、自身を元にしているバージョンは2しかありません。次に新たな変更が加えられた場合は、バージョン2を元にしてバージョン3が作られることになるので、バージョン1を元にしたのは引き続きバージョン2のみのままです。

対象のプロジェクトにおいて、ひとりで作業をしている場合はこれでも問題ないのですが、複数人で作業をしている場合これだと問題が起こる可能性があります。

作業の途中でお互いにコミットしていると、相手のコミットが自分自身の作業に対して影響を与えてしまう可能性があり、これは作業の効率を大きく下げる要因になりえます。

このような事態を防ぐために、ブランチという仕組みがあります。

ブランチは、ひとつのバージョンを元にした新たなバージョンを、複数個、並列で管理することを可能とします。

イメージとしては、バージョン1を元にして、バージョン2aと、バージョン2bの2つを作ることができるということです。

ブランチを使用すると、複数人で作業をしていても、ひとりはバージョン2a→3aと進めていき、もうひとりはバージョン2b→3bと進めていくことで、お互いの影響を受けることなく作業を進めることができます。

ここから、ブランチに関連するgitのコマンドを見ていきましょう。

【git branch】新規ブランチを作成する

新規のブランチは以下のコマンドで作成することができます。

コマンド:git branch <ブランチ名>

git branchコマンドは、ブランチを作成する以外の機能もあります。ブランチ名を指定せずに、git branchコマンドを実行すると、現在作成されているブランチの一覧を表示することができます。

ブランチを作成したら、意図した通りの名前で作成されているかどうかをgit branchコマンドで必ず確認するようにしましょう。

【git checkout】ブランチを切り替える

ブランチを切り替えるには、git checkoutコマンドを使用します。

コマンド:git checkout <ブランチ名>

git branchコマンドを実行するとブランチの一覧を表示できますが、その際、カレントブランチ(=現在選択されているブランチ)は、ブランチ名の先頭にアスタリスク(*)が表示されます。

ブランチを切り替えた後は、git branchコマンドを実行し、アスタリスクが想定したブランチの前に移動していることを確認するようにしましょう。

【git merge】ブランチをマージする

枝分かれさせたブランチは、最終的には統合する必要があります。複数のブランチを統合することをマージと言います。

gitでマージを行うには、以下のコマンドを使用します。

コマンド:git merge <ブランチ名>

コマンドを実行すると、指定したブランチの内容がカレントブランチに統合されます。

指定したブランチの内容をインプットにしてカレントブランチの内容を変えるイメージなので、内容が変更になるのはカレントブランチだけです。

もし、指定したブランチとカレントブランチで同じファイルを編集していた場合、コンフリクトが発生します。

コンフリクトが発生すると、以下のようなメッセージが表示されます。

コンフリクト発生時のメッセージ

Auto-merging after.txt
CONFLICT (content): Merge conflict in after.txt
Automatic merge failed; fix conflicts and then commit the result.

※1行目と2行目の最後にある「after.txt」がコンフリクトが発生したファイル名です。

コンフリクトが起きた場合、ワークツリーのファイルには両ブランチの内容が反映された状態になります。

どのファイルがコンフリクトしているかを確認するためには、git statusコマンドを使用します。

コンフリクトを解消するためには、対象のファイルを編集し、最終的にコミットしたい形に編集します。<<<や>>>、===などのgitが自動で挿入する行がありますが、これらは削除する必要があります。

以下は、コンフリクトしたファイルのサンプルです。

コンフリクトが発生したファイル

aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
<<<<<<< HEAD
mod1
=======
mod2
>>>>>>> conf

aaaaaa〜eeeeeeまでは、両方のファイルに共通して記載されていた内容です。<<<<<<< HEADはgitが自動で挿入した内容で、その下のmod1が統合先(マージ実行時点でのカレントブランチ)で行われていた修正です。=======もgitが自動挿入した内容で、その下のmod2が統合元で行われていた修正です。最後の行は、gitが自動で挿入した行であり、最後に書いてあるconfは、統合元のブランチ名です。

編集が終わったら、通常のコミットと同じように、git addgit commitの順で実行します。

これで、コンフリクトが解消できます。

【git branch -m】ブランチ名を変更する

ブランチ名を変更するには、以下のコマンドを実行します。

コマンド:git branch -m <ブランチ名>

名前を変更したいブランチを選択(=カレントブランチに)した上で、上記のコマンドを実行します。<ブランチ名>には変更後のブランチ名を指定します。

【git branch -d】ブランチを削除する

ブランチを削除するには、以下のコマンドのうちのいずれかを実行します。

コマンド①:git branch -d <ブランチ名>

コマンド②:git branch -D <ブランチ名>

どちらのコマンドでもブランチを削除できます。コマンド①で削除する場合、切り出し元へマージされていない変更があると、メッセージが表示され、ブランチは削除されません。

一方で、コマンド②を使用すると、マージ未済みの変更があったとしても強制的にブランチを削除することができます。

基本的にはコマンド①を使用して削除するようにしましょう。

リモート・リポジトリとのやりとり

ここからは、リモート・リポジトリとのやりとりに使用するコマンドを紹介します。

【git clone】リモート・リポジトリをもとにプロジェクトを開始する

リモート・リポジトリをもとにローカルでプロジェクトを開始するには、以下のコマンドを実行します。

コマンド:git clone <リポジトリ名>

リポジトリ名はURL形式で指定します。githubであれば、対象プロジェクトのCodeボタンから「Copy url to clipboard」を押下するとコピーできます。

git cloneコマンドを使用してプロジェクトを作成すると、作成されたローカル・リポジトリと、作成元となったリモート・リポジトリの内容が自動的に関連づけられます。

関連づけられたリモート・リポジトリに対しては、コマンド実行時に参照するためのショートカット名が割り当てられます。git cloneコマンドを使用してプロジェクトを作成した場合には、作成元のリモート・リポジトリのショートカット名は「origin」になります。

git remote -vコマンドを実行すると、関連づけられたリモート・リポジトリのショートカット名とリポジトリ名(URL)を確認することができます。

【git remote add】リモート・リポジトリにショートカット名を割り当てる

git cloneコマンドを使用してプロジェクトを作成した場合はショートカット名(origin)が自動的に割り当てられます。しかし、git initコマンドを使用してローカルのプロジェクトを作成した場合、リモート・リポジトリとの紐付けを別途行う必要があります。

リモート・リポジトリとの紐付けには、git remote addコマンドを使用します。

コマンド:git remote add <ショートカット名> <リポジトリ名>

<リポジトリ名>には、git cloneコマンドのところで説明したURL形式の名称を指定します。

<ショートカット名>は、コマンド実行時にリモート・リポジトリを指定するための名称で、git clone実行時に「origin」となっていたものです。任意の名前を指定できますが、「origin」とするのが通例です。

【git push】ローカルの変更をリモート・リポジトリに反映する(プッシュ)

ローカル・リポジトリにコミットした変更は、git pushコマンドを使用することで、リモート・リポジトリに反映することができます。

コマンド:git push <ショートカット名> <ブランチ名>

<ショートカット名>は反映先のリモート・リポジトリを指定します。そして、<ブランチ名>には、そのリモート・リポジトリの中にある反映先のブランチを指定します。

なお、-mオプションを指定してgit pushコマンドを実行すると、次回以降、ショートカット名とブランチ名の指定を省略することができます。

コマンド(初回):git push -m <ショートカット名> <ブランチ名>

コマンド(2回目以降):git push

リモート・リポジトリの変更をローカルに取り込む方法

リモート・リポジトリに対して別の人が反映した変更をローカルに取り込むには、git fetchコマンドかgit pullコマンドのいずれかを実行します。

git fetchコマンドを使用すると、リモート・リポジトリの内容をローカルにダウンロードすることができます。ダウンロード後にgit mergeコマンドを使用することで、ローカルのプロジェクトへの反映が完了します。

git pullコマンドは、git fetchコマンドとgit mergeコマンドを一度に実行するためのコマンドです。

【git fetch】リモート・リポジトリの内容をフェッチする

git fetchコマンドを実行すると、リモート・リポジトリの内容をローカルにダウンロードすることができます。

コマンド:git fetch <ショートカット名>

ダウンロードされた内容は、リポジトリの内容を保存するエリアにのみ保管されます。

この、リモート・リポジトリの内容が保存されるエリアをリモートブランチと言い、「remotes/<ショートカット名>/<ブランチ名>」という名称が割り当てられます。

なお、リモートブランチを表示するには、git branch -aコマンドを使用します。-aオプションを指定しないとリモートブランチは表示されません。

git fetchコマンドを実行した時点では、リモートブランチにリモート・リポジトリの内容がダウンロードされるだけで、ワークツリーやローカル・リポジトリの内容は変更されません。

ワークツリーやローカル・リポジトリに変更を反映するためには、git mergeコマンドを使用して、ダウンロードしたリモートブランチの内容をマージする必要があります。

コマンド:git merge <ブランチ名>

リモートブランチのマージを行う際、ブランチ名は「remotes/」より後の部分だけを入力します。

もし、「remotes/origin/main」というリモートブランチをマージしたいのであれば、以下のコマンドを実行することになります。

コマンド:git merge origin/main

【git pull】リモート・リポジトリの内容をローカルプロジェクトに取り込む

git fetchgit mergeの流れを一度のコマンドで実行できるのが、git pullコマンドです。

コマンド:git pull <ショートカット名> <ブランチ名>

git fetchコマンドでは、リモート・リポジトリのショートカット名を指定してローカルにダウンロードしてから、取り込みたいブランチを指定してマージをする必要がありました。

git pullでは、ダウンロードとマージを連続で実行するため、ショートカット名とブランチ名の両方を指定する必要があります。

リベース

リベースとは、2つのブランチを統合する方法のひとつです。ブランチを統合する方法としては、git mergeコマンドを使用してマージする方法を先に取り上げましたが、リベースは、マージとは別の方法です。

リベースとマージの最大の違いは、統合した後の履歴の残り方です。

マージをした場合、マージによって作成されたコミットは、親コミットが2つになる可能性があります。これは、統合元の最新のコミットと統合先の最新のコミットの両方が親コミットになるためです。

一方で、リベースでは、親コミットが複数になることはありません。リベースによって作られるコミットは、統合先のみを親とし、統合元のコミットが親コミットにならないためです。

最新世代から順番にコミットを遡って行った時に、途中で分岐を発生させる可能性があるのがマージ、その可能性がないのがリベースと言い換えることもできます。

2つのブランチを統合する際、通常はマージを使うことが多いと思います。リベースを使うのはあくまで履歴を一直線にしたい(つまり、コミットを遡って行った時に分岐を発生させたくない)場合だけということになります。

【git rebase】リベースでブランチを統合する

リベースを行うには、以下のコマンドを使用します。

コマンド:git rebase <ブランチ名>

ブランチ名のところには、カレントブランチ(=現在選択されているブランチ)の内容をどこに反映させるのかを指定します。つまり、統合先を指定することになります。

この指定方法はgit mergeコマンドとは逆です。git mergeコマンドではカレントブランチが統合先となり、コマンドで統合元を指定します。

git rebaseコマンドを実行すると、カレントブランチの内容が指定したブランチに反映されます。このとき、統合先の最新世代のあとに、カレントブランチのコミットが順番に反映されていくかたちで、ブランチが一本に統合されます。

たとえば、コミットAでfeatureブランチを作成し、mainブランチはA→A1→A2という形で進んでいたとします。また、featureブランチはA→B1→B2と進んでいたとしましょう。このとき、featureブランチでgit rebaseコマンドを実行しmainブランチを指定すると、A→A1→A2→B1→B2という並びでブランチが統合されます。

git rebaseコマンドを実行した後、統合先のブランチ(上記の例でいうmainブランチ)を統合元(同、featureブランチ)にマージする必要があります。リベースした直後は、統合先(mainブランチ)の最新コミットがA2のままになっているためです。

mainブランチにおいて、featureブランチを指定してgit mergeコマンドを実行することで、mainブランチの最新コミットがfeatureブランチの最新と同じもの(B2)になり、ブランチの統合が完了します。

スタッシュ

スタッシュとは、作業中の内容を一時的に退避しておくための機能です。スタッシュを使用すると、ワークツリーとステージの内容を、一時的に専用の領域に保存しておくことができます。

あるブランチでの作業をコミットする前に、別のブランチで作業する必要が生じた場合などに便利な機能です。

【git stash】作業内容を一時的に退避する

作業中の内容を保存するには、以下のコマンドを使用します。

コマンド:git stash save

※(saveは省略可能)

git stashコマンドを実行すると、作業中のファイルが専用の領域に退避され、ワークツリーとステージの内容が前回コミット時点に戻ります。

【git stash list】退避された情報の一覧を表示する

退避された情報は、git stash listコマンドで一覧表示することができます。

コマンド:git stash list

上記のコマンドを実行すると、退避されたスタッシュの名称や基準となるコミットなどの情報が一覧形式で表示されます。

スタッシュには、「stash{0}」や「stash{1}」などの名称が割り当てられます。この名称は退避した内容を復元するときに使用します。

【git stash apply】退避された情報を復元する

退避されていた情報を戻すには、git stash applyコマンドを使用します。

コマンド:git stash apply

このコマンドを実行すると、最後に退避されたスタッシュの内容が復元されます。このとき、復元されるのはワークツリーの内容だけで、ステージの内容は復元されません。

ステージの内容も復元したい場合は、-- indexオプションを使用します。

コマンド:git stash apply --index

ひとつのワークツリーに対してスタッシュは複数回行うことができますが、最新版以外のスタッシュを戻すには、対象となるスタッシュの名称を指定します。

コマンド:git stash apply <スタッシュ名>

スタッシュ名には、git stash listコマンドを実行したときに表示されるstash{0}やstash{1}といった文字列を指定します。

【git stash drop】退避された情報を削除する

退避された情報を削除するには、git stash dropコマンドかgit stash clearコマンドを使用します。

git stash dropコマンドは、指定したスタッシュをひとつ削除するコマンドです。対象となるスタッシュはスタッシュ名で指定します。指定を省略した場合は、最新のスタッシュが削除されます。

コマンド:git stash drop <スタッシュ名>

コマンド:git stash drop

git stash clearコマンドを使用すると、退避されているすべてのスタッシュを一括で削除することができます。

コマンド:git stash clear

タグ

タグ機能を使用すると、特定のコミットに対して目印をつけることができます。これは、本番環境にリリースしたバージョンなど、何かキーポイントになるようなバージョンを後から確認できるようにするために使用します。

タグには2種類あります。軽量タグと注釈付きタグです。軽量タグは、ただ単に特定のコミットに対して印をつけるだけですが、注釈付きタグは、作成者や作成日時、メッセージといった追加情報を合わせて保存することができるという違いがあります。

【git tag】コミットにタグを付与する(軽量タグ)

コミットに軽量タグを付与するには、以下のコマンドを使用します。

コマンド:git tag <タグ名>

git tagコマンドを実行すると、最新のコミットに対して指定した名称のタグが作成されます。

【git tag -a】コミットにタグを付与する(注釈付きタグ)

注釈付きタグは、以下のコマンドで付与します。

コマンド:git tag -a <タグ名> -m “<メッセージ>”

-aオプションは、タグが注釈付きタグであることを意味するオプションです。-mオプションは、その後に入力する内容をメッセージとして付与することを意味するオプションです。

軽量タグと同様に、上記のコマンドを実行すると、最新のコミットに対してタグが付与されます。

【git tag】付与されたタグを一覧表示する

付与されたタグはgit tagコマンドで一覧表示することができます。

コマンド:git tag

また、-lオプションを使用すると、特定のパターンに合致した名称のタグだけが表示されます。

コマンド:git tag -l "<パターン文字列>"

パターン文字列には、以下のような記号を使用することができます。

  • *:0文字以上の任意の文字列
  • ?:1文字の任意の文字列

たとえば、「v1.」で始まる名称のタグをすべて表示したい場合には、以下のコマンドを実行します。

コマンド:git tag -l “v1.*”

【git show】タグの詳細を表示する

タグの詳細情報を表示するには、以下のコマンドを使用します。

コマンド:git show <タグ名>

タグ名に軽量タグを指定した場合は、タグが紐付けられているコミットの作成者や作成日時などの詳細情報が表示されます。注釈付きタグの場合は、コミットの情報に加えて、タグ自体の作成者や作成日時、メッセージなどの情報が表示されます。

【git push】タグをリモートリポジトリに送信する

タグは、ローカル環境で作成しただけではリモート・リポジトリへ送信されません。また、タグに紐付けられたコミットをプッシュしても、タグは送信されません。

タグをリモート・リポジトリへ送信するには、以下のコマンドを使用します。

コマンド:git push <ショートカット名> <タグ名>

リポジトリのショートカット名と送信したいタグ名を指定します。これにより、指定されたタグの情報がリモート・リポジトリへと送信されます。

リポジトリに紐付けられているすべてのタグを送信するには、--tagsオプションを指定します。

コマンド:git push <ショートカット名> --tags

おわりに

基本的なgitのコマンドを解説しました。ここまでで紹介したコマンドを使えるようになれば、ある程度gitを使用した作業ができるようになるのではないでしょうか。

gitには他にもいろいろな機能があります。基本的な使い方に慣れてきたら、ぜひ公式サイトなどを活用して他の機能の学習も進めてみてください。