独り言

プログラミングの講師をしています。新人研修で扱う技術の解説と個人の技術メモ、技術書の紹介など

【Git】Git入門(概要と用語の解説)

ここではシステム開発の中でもよく使用されるGitと呼ばれるツールについて解説します。
まずはGitの概要と、Gitの操作の中で使用される用語について解説します。


バージョン管理システム入門

Gitの詳しい解説に入る前に、まずはバージョン管理システムとは何かについて簡単に知っておきましょう。

Gitとは

Gitとは、バージョン管理システムと呼ばれるツールの一つです。
読み方は「ギット」です。
バージョン管理システムと呼ばれるものは、いくつかの種類がありますが、これを書いている時点で最もメジャーで多く使用されているバージョン管理システムがGitです。

バージョン管理システムとは

そもそもバージョン管理システムとは何でしょう。
バージョン管理システムとは、ファイルの変更の履歴を管理するためのツールです。
自由なタイミングで「誰が」「いつ」「何を」修正したかの履歴を残しておくことができます。
つまり、バージョン管理システムでファイルをバージョン管理しておけば、履歴を見ることでファイルに対して誰がいつ何を変更したかが簡単に分かるようになります。

バージョン管理は特にプログラム開発の際などに重宝します。
開発をしている中で、昨日までは正常に動いていたのに、今日ファイルをいくつか修正したら正常に動作しなくなった。
といったことがよく起こります。
そして、どの部分を修正したのかを正確に覚えておらず、記憶を頼りに元の状態に戻そうとしてもうまくいかない。
という経験があるエンジニアは多いかと思います。
仮にバージョン管理していれば、今日の時点でどの部分が変更されたのかを確認することも簡単に行え、かつ、ファイルを以前の状態に戻すことも可能です。

また、システム開発をしていると、一つのシステムに対して複数の作業を行いたい場合があります。
例えば、バグ修正、新しい機能の追加、既存の機能の改善、等です。
複数人の人がこういった作業を同時に行った場合、同じファイルを複数の人が修正してしまう可能性があります。
この場合、後から作業した人が前に作業していた内容を上書きしてしまい、修正した内容が消えてしまう、といったことが起きてしまう可能性があります。

バージョン管理を行っている場合、ブランチという機能が使えます。
ブランチを使うと、複数人で同時に作業する場合に、お互いに影響を与えずに作業を行うことが可能になります。

バージョン管理システムの種類

バージョン管理システムには様々なツールがありますが、履歴の管理方法という観点から大きく2つの種類に分けられます。

  • 集中管理方式
  • 分散管理方式

の2種類です。
最近の主流は分散管理方式となっており、Gitも分散管理方式に分類されます。

2つの違いを簡単に説明します。

集中管理方式

それぞれの管理方式の説明に入る前に、まずバージョン管理でよく使用される用語を一つ紹介します。
バージョン管理システムには「リポジトリ」と呼ばれるものが存在します。
リポジトリとは、日本語では貯蔵庫という意味があります。
簡単に言うとファイルの変更履歴の情報を保持するデータベースのことです。
つまり、「誰が」「いつ」「何を」修正したのかの情報は全てリポジトリに格納されていることになります。

ここからは管理方式についての説明です。
集中管理方式は、一つのリポジトリを複数人で共有して使用するバージョン管理システムです。
通常はサーバーを用意して、そこにリポジトリを作成し、チーム間で共有します。

集中管理方式の代表的なツールには

があります。
SVNCVSを元に作成されたもので、集中管理方式の中ではおそらくSVNが最も利用されているバージョン管理システムです。

集中管理方式の欠点は、サーバーに接続された状態でないとバージョン管理が行えないという点です。
ネットワークに接続されていない状況だったり、別の場所で作業していて社内のサーバーにつながらない状況ではバージョン管理できません。
バージョン管理をする場合、サーバーに接続できる状態が必要です。

この欠点を解決するために開発されたのが、分散管理方式のバージョン管理システムです。

分散管理方式

分散管理方式と集中管理方式の大きな違いは、集中管理方式ではリポジトリが1つだったのに対し、分散管理方式ではリポジトリが複数あるということです。
分散管理方式のリポジトリは、「ローカルリポジトリ」と「リモートリポジトリ」という2種類のリポジトリがあります。

ローカルリポジトリは、自分のPCに存在するリポジトリです。
ローカルリポジトリでは、ネットワークにつながっていない状態でも、自分のPC内で完結するようなバージョン管理が行えます。
リモートリポジトリは、通常はサーバー上に作成されたリポジトリのことで、複数人で作業する際にチーム間で共有されるリポジトリになります。

リモートリポジトリによって複数人でファイルの履歴を共有しつつ、ローカルリポジトリを活用することで自分のPCだけでもバージョン管理が行えることが、分散管理方式のバージョン管理システムの利点となります。

つまり分散管理方式の場合、ある程度ローカルリポジトリで開発を進めて、作業に一区切りついた段階で、まとめてリモートリポジトリに反映させることが可能です。

分散管理方式の代表的なツールは

があります。
この中でも最も主流となっているのがGitです。

バージョン管理の目的

バージョン管理システムでできることは最初に述べましたが、改めてバージョン管理システムを使う目的を説明しておきます。

開発のスピードが上げるため

バージョン管理していると、修正履歴をリポジトリに反映させる作業を行う必要があるため、その分の手間は増えます。
しかし、履歴を管理していることで、バグや問題が発生した場合の調査が楽になったり、問題発生前のバージョンに戻すことが簡単にできます。
また、ブランチの機能を使用することで、複数の作業を同時並行で行うことができます。
つまり、結果的に開発のスピードが上がります。

余分なソースコードを消すため

ソースコードを修正するとき、既存のソースコードコメントアウトして、日付などをコメントとして残して修正することがあります。
そうしておけば、ソースコードを見るだけで修正の履歴を見ることができるため、履歴を確認したい時は便利です。
しかし、動いているソースを確認したい時は、過去の修正履歴のソースコードは邪魔です。
バージョン管理をしておけば、過去の修正履歴はリポジトリに残っているので、最新のソースコードに残しておく必要がありません。
結果的にバージョン管理をすることによって、無駄なソースコードを残さずに済みます。
その結果シンプルなソースコードを保つことができます。


Gitに関連するツールの紹介

Gitはこれまでに説明したように、バージョン管理を行うためのツールです。
Gitはインストールすればすぐに利用することができますが、Gitを効果的に使うために、様々なツールやサービスが用意されています。
ここではGitの導入や、関連するツールやサービスについて紹介します。

Git

ここで改めてGitについて説明しておきます。
Gitは分散管理型のバージョン管理システムです。
先に述べたように、Gitの機能を有効活用することで開発を効率よく行うことが可能になります。

Gitは元々、Linuxカーネルの開発を効率よく行うために開発されました。
Linuxカーネルは、サーバー用のOSであるLinuxの中核となる部分です。
プロジェクトの規模が巨大であるため、リポジトリの操作が高速であることが求められました。
そのため、Gitはリポジトリ操作を高速にするための工夫がされていて、それがGitの特徴でもあります。

Gitの導入

Gitは誰でも無料で使用することが可能です。
WindowsMacの場合、公式サイトからインストーラがダウンロードできます。

https://git-scm.com/

インストーラをダウンロードして、指示に従ってインストールを行うとGitが使用できるようになります。

Git操作のツール

Gitを操作するためのツールには様々な種類があります。
ここではWindowsでGitをインストールしたという前提で話を進めます。
Gitを単体でインストールした場合、「Git Bash」というコマンドラインツールと、「Git GUI」という簡易的なGit操作用のGUIツールが使用可能です。

Git Bashでは、コマンド操作でGitを操作します。
BashとはLinuxOSを操作する際によく使用されるシェルというソフトウェアです。
Git BashがあればGitの操作は全て行うことができますが、コマンドを覚える必要があり、また、コマンド操作に慣れていない人も多いかと思います。

そこで、Gitの操作を直観的に行えるようにするためのGUIツールが用意されています。
Gitをインストールした段階では「Git GUI」というGUIツールがありますが、GUIで操作する場合、他に操作性が良いツールがたくさんあるため、別でインストールした方が良いでしょう。

GitのGUIツールは公式サイトでも色々と紹介されています。

https://git-scm.com/downloads/guis/

上記のサイトでは多くのツールが紹介されていますが、サイトや入門書で解説が多いのは「SouceTree」と「GitHub Desktop」です。
利用者が多いツールの方がネット上の情報も多く、Gitの入門書でも操作方法を解説しているものが多いので、GUIツールを使用する場合はこの2つのいずれかを使用すると良いでしょう。

Windowsの場合、「TortoiseGit」というツールも操作しやすく便利です。
エクスプローラー上で右クリックからGitに関する操作をすることができます。

複数のツールを導入して試してみて、自分が使いやすい、見やすいと感じるものを使用すると良いでしょう。

開発ツールとの連携

プログラム開発をする場合、テキストエディタIDE(統合開発環境)を使用して開発を行うことでしょう。
最近はテキストエディタIDEの画面からもGitの操作ができるもの多くあります。
VS Code(テキストエディタ)では、最初からGitを操作するための機能がついており、Gitのインストールさえしておけば、VS Codeの画面からGitの操作ができるようになっています。
他にも「Eclipse」や「Visual Studio」といったIDEでもGitの操作を行うことができます。

詳しくは後述しますが、複数人で開発を行う場合、一つのファイルに対しての修正を複数人が行うことで、競合(コンフリクト)が発生することがあります。
この時、手動でファイルの内容を修正する必要があるのですが、これを解決するときにはIDEからのGit操作の方が直観的にファイル修正がしやすく便利です。
ですのでIDEによる開発を行う場合、IDEでのGit操作に慣れておくと良いでしょう。

Gitのホスティングサービス

Gitのホスティングサービスと呼ばれるサービスがあります。
これはインターネット上でGitのリポジトリの機能を提供してくれるサービスです。
主な用途としては、複数人で作業をする場合にリポジトリを共有する目的として利用されます。
複数人でリポジトリを共有するには、リモートリポジトリをします。
リモートリポジトリは自分でサーバーを用意して作成することもできますが、Gitのホスティングサービスを利用することで、面倒なセットアップ作業などをせずともすぐにリモートリポジトリとして利用することができます。

Gitのホスティングサービスは1人で作業する場合でも役に立ちます。
インターネット上にリポジトリを作成しておくことで、複数にPC端末でファイルを共有することができます。

以下、Gitのホスティングサービスとしてよく利用されているものを紹介します。  

GitHub

GitHubはGitのホスティングサービスの中で最も有名で多くの人に利用されています。
public(外部へ公開する)のリポジトリはいくつでも作成可能です。
private(外部非公開)のリポジトリもいくつでも作成可能ですが、共有できるのは3人までなど、いくつかの制限があります。
これらの制限を気にせずに利用する場合には有料のプランが必要になります。  

2018年までは無料のプランではprivateのリポジトリ自体作成することができませんでしたが、2019年からは制限内ならprivateのリポジトリも作成可能になりました。  

Bitbucket

Atlassian社が提供しているGitのホスティングサービスです。
プライベートのリポジトリは無制限に作成可能で、5ユーザーまでの共有が可能です。
Atlassian社はSouceTreeも提供しています。
そのためBitbucketはSouceTreeとの連携が得意です。

GitLab

TODO

ここまでまとめ

  • バージョン管理システムとは、ファイルの操作履歴を管理するシステムのこと。
  • バージョン管理システムは、分散型と集中型に分かれる。
  • 最近の主流は分散型で、その中でも最もメジャーなツールがGit。
  • バージョン管理を行うことで、開発スピードが上がり、余分なソースを削除できる。
  • Gitはコマンドで操作するが、GUIで操作するためのツールとして、SourceTreeやTortiseGitがある。
  • チームで作業を行う場合は、リモートリポジトリが必要。 リモートリポジトリを提供しているサービルに、GitHub、BitBucket、GitLabなどがある。

用語の説明

ここではGitを使用する上で知っておくべき用語を一通り解説します。

Gitの3つのエリア

Gitを使って作業を行うにあたり、知っておかなければいけない3つのエリアがあります。
まずはその3つの領域について解説します。

作業ディレクト

作業を行う(ファイルを追加したり編集したりする)ディレクトリ(フォルダ)のことです。
ワーキングディレクトリ、ワークツリーなどとも呼ばれます。

Gitリポジトリ

ファイルの変更履歴を保存する場所です。
単にリポジトリとも呼ばれます。
実体は、「.git」という隠しファイルです。
Windowsではデフォルトの設定では.(ドット)から始まるファイルやフォルダはエクスプローラ上には表示されないようになっています。

エクスプローラの表示タブから、「隠しファイル」のチェックボックスにチェックを入れると表示されるようになります。

Gitのリポジトリが作成されるのは、gitのコマンドやGUIツールを使ってリポジトリを初期化した場合、もしくはリモートリポジトリをクローンした場合です。

ステージングエリア

Gitではバージョン管理の対象としたファイルは、変更履歴をリポジトリに反映させる前に、ステージングエリアと呼ばれる領域に移すことになっています。
リポジトリに反映させるまでの手間が増えるため、最初は面倒に感じますが、このような仕組みにすることで、細かい作業単位での履歴の反映が行いやすくなります。
ステージングエリアはインデックスと呼ばれることもあります。

Gitでバージョン管理をする場合、

  1. 作業ディレクトリで作業を行う
  2. 履歴を反映させたいファイルをステージングエリアに反映させる
  3. リポジトリに反映させる

という流れになります。

リポジトリ

リポジトリについてはあたらめて説明しておきます。
リポジトリとはファイルの履歴を保存しておくデータベースのことで、Gitではローカルリポジトリとリモートリポジトリの2つに分けられます。

ローカルリポジトリ

自分のPC内に存在するリポジトリのことです。
Gitがインストールされていれば、任意のフォルダに作成可能です。
PC内にいくつでも作成することが可能です。
通常はバージョン管理するプロジェクトごとにリポジトリを作成することになります。

リモートリポジトリ

複数人で共有することを目的としたリポジトリです。
誰かのローカルリポジトリをリモートリポジトリとして扱ったり、自分でサーバーを立ててリモートリポジトリを作成することもできます。
通常はGitのホスティングサービス(GirHubやBitbucket)を利用してリモートリポジトリを作成することが多いでしょう。


操作

操作に関する用語をまとめておきます。
この部分を先に読んでもイメージがしにくいかもしれないので、その場合は、先に実習で手を動かしつつ、用語を整理したい時にまたここを読む、でもいいでしょう。

コミット

ファイルの変更内容をローカルリポジトリに反映させること。
コミットは、ステージングエリアの内容に対して実行されます。

コミットID

コミットの際に生成される40桁の英数字。
このIDによりコミットを一意に特定することができます。
ファイルの状態を特定のコミットの状態に戻したい場合などに、このIDを指定する。
コミットIDはSHA-1という演算方式により算出されたハッシュ値です。
コミットを識別するだけの値であれば、連番でもいいのでは?と思う方もいるかもしれません。
しかし、コミットIDは連番では問題があります。
Gitではブランチと呼ばれる機能を使うことで、履歴の流れを分岐させて、別々の作業を並行して行うことができます。
また、リモートリポジトリを使うことで、同じプロジェクトでも複数人がローカルでバージョン管理を行うことが可能です。
そうしたとき、それぞれのブランチを統合する際、コミットIDが重複してしまうと、履歴が判断できなくなってしまいます。
コミットIDを連番にしてしまうと、どこかで値が重複してしまう可能性があります。
そのため、修正内容などからハッシュ値を計算してコミットIDとすることで、コミットIDが重複しないようにしています。

コミットメッセージ

Gitではコミットを行う際には、必ずコメントを書く必要があります。
その時のコメントのことをコミットメッセージと言います。
メッセージはどのような作業をしたのかが分かりやすく書くことが求められます。
例えば、「いくつかのファイルを修正」などと書いてしまうと、
具体的に何を修正したのかが分かりません。
1つの作業単位でコミットし、明確なメッセージを書くようにしましょう。

また、メッセージは一般的な書き方が決まっています。
1行目:変更の概要
2行目:空白
3行目:詳細

リバート

コミットを打ち消す操作のこと。
実際には過去のコミットを消すわけではなく、反対の内容で新規のコミットを作成している。

リベース

ブランチを取り込んで、履歴を一直線にする操作のこと。
マージの場合、過去のコミットの履歴は改変されず、マージするための新しいコミットが作成されます。
リベースの場合は、もともとのコミットを改変されてリベース先のブランチに乗っかって履歴が一直線になります。
re + base ブランチの付け根を植え替えるイメージです。
履歴を改変するので、マージよりも危険性がある。慣れないうちはマージだけで問題ありません。

スカッシュ

複数のコミットを一つにまとめる操作のこと。
スカッシュを行う場合、対象のコミットがローカルリポジトリにしかないことを確認してから行いましょう。
※リモートリポジトリにあるコミットを改変すると、他のメンバーが混乱します。

スタッシュ

作業ディレクトリの変更内容を一時的に別の場所に退避しておく操作のこと。

チェリーピック

別のブランチから特定のコミットを取り込むこと。

タグ

コミットに対する目印。
履歴上の需要なポイントに目印を付けることで、名前を付けやすくなる。


ブランチに関する用語

ブランチ

ブランチは直訳すると枝のことです。
Gitではコミットをするたびに、その履歴が1つの流れとしてつながっています。
ブランチはその履歴の流れを分岐させることができる機能です。

ブランチを分けると、別のブランチでの作業の影響を受けずに作業をすることができます。
作成する機能が複数ある場合に、機能ごとにブランチを分けたり、バグ修正と機能追加など、役割毎にブランチを分けることで、お互い干渉せずに自分の修正に専念することが可能になります。
Gitではリポジトリを作成した時点ではmasterと呼ばれるブランチが1つだけある状態です。
ブランチは任意の名前でいくつでも増やすことが可能です。

HEAD

今いるブランチを指すポインタ。
.git/HEADの中身で確認することもできる。

マージ

ブランチを分けて作業を行った場合、最終的にはそれぞれのブランチの修正内容を1つのブランチに統合する必要があります。
この統合する作業のことをマージと呼びます。

競合(コンフリクト)

マージをする際、同じファイルの同じ個所を別々の人が修正してしまった場合、Gitはどれを最新に反映させればよいのか判断できません。
この時に発生するのが競合(コンフリクト)です。
競合が発生した場合は、手動で競合したファイルを修正し、新たにコミットし直す必要があります。


リモートリポジトリに関する操作

プッシュ

ローカルリポジトリの変更内容をリモートリポジトリに取り込ませること。

プル

リモートリポジトリの更新内容とローカルリポジトリに取り込むこと。

フェッチ

リモートリポジトリから最新情報をダウンロードしてくること。
プルと似ていますが、実際には少し違っていて、
プル = フェッチ + マージ
となっています。
フェッチはあくまでもダウンロードするだけで、プルはダウンロードした後にそのまま取得したブランチをマージします。

クローン

リモートリポジトリをローカルにローカルリポジトリとして複製すること。
ローカルリポジトリを作成する方法は主に2つあります。
一つは作業ディレクトリに対して初期化の処理を行い、リポジトリを新しく作成する方法。
もう一つは、既存のリモートリポジトリをコピーしてくる方法。
後者のローカルリポジトリの作成方法がクローンです。

フォーク

他人のアカウントのリポジトリを自分のアカウントにコピーすること。
例えば、他人のGitHubのアカウント上にある公開されたリポジトリを、自分のGitHubアカウントにコピーすること。

プルリクエス

自分のアカウントの変更内容を他人のリポジトリに取り込んでもらうように提案すること。
プッシュした後にプルリクエストを行う。
プルリクエストを依頼された側は、リクエストの内容を確認し、問題がなければマージを行う。