100日後にエンジニアになるキミ - 53日目 - Git - Gitについて

昨日までのはこちら

[100日後にエンジニアになるキミ - 42日目 - クラウド - クラウドサービスについて](https://qiita.com/otupy/items/d1765f1541a104ed6133)

[100日後にエンジニアになるキミ - 36日目 - データベース - データベースについて](https://qiita.com/otupy/items/7af17635d576677606dc)

[100日後にエンジニアになるキミ - 24日目 - Python - Python言語の基礎1](https://qiita.com/otupy/items/6d1e5453f530e07b7aec)

[100日後にエンジニアになるキミ - 18日目 - Javascript - JavaScriptの基礎1](https://qiita.com/otupy/items/2f71d5f9c754b29d9555)

[100日後にエンジニアになるキミ - 14日目 - CSS - CSSの基礎1](https://qiita.com/otupy/items/61a97863f6df14171994)

[100日後にエンジニアになるキミ - 6日目 - HTML - HTMLの基礎1](https://qiita.com/otupy/items/cd2315dcb38671cfded0)



最近の開発ではGitが欠かせません。
本日はGitの仕組みについてです。

## Gitとは

Git(ギット)とは何でしょうか？
プログラムのソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システムです。

Linuxカーネルのソースコード管理に用いるために
リーナス・トーバルズによって開発されました。

多人数での開発、変更の履歴を記録しているので
いつでも昔のファイルを参照できます。

分散型と言っているのは
ネットワークにアクセスできない状態でも
履歴の調査や変更の記録といったほとんどの作業を行うことができるためです。

バージョン管理ツールを導入していない場合は
差分の変更や間違いを元に戻すことなどが手間がかかります。
そのため大規模開発ではバージョン管理ツールの利用が必須になるので
覚えておきましょう。

ソフトウェアであるのでPCやサーバーにインストールをすることで
使えるようになります。

## Gitのバージョンについて

Gitはファイル群を丸ごと記録する際にバージョンを付けて記録を行います。
バージョンを付けておくことで、以前の状態に戻すことができるようになります。

またGitではファイルをスナップショットとして丸ごと記録・保存しています。
大規模開発の際にはファイルが丸ごと保存されているため素早く変更や統合ができるようになります。

![git1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379626/02e6fcd2-ab5e-38bd-2592-871e0e1c4a24.png)

## GitHubについて

上記でも説明している通り
`Git`は`バージョン管理ソフトウェアの名前`です。

それに対して`GitHub`は
`Gitを利用した、開発者を支援するWebサービスの名前`です。

<img width="632" alt="スクリーンショット 2020-05-12 17.33.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379626/5678af33-7acd-7831-ebb9-f55b60041caf.png">

ソフトウェアとサービスの違いなので
インドネシアとインド料理くらい違います。

`Git`を使うにはサーバーとなるものを用意しなければいけません。
別途クラウドサービスなどでサーバーを借りてきたりして`Git`をインストールしないと
すぐには使えません。

それに比べると`GitHub`はアカウントさえ持っていれば
すぐに使うことができます。
まさにGitのハブ(Hub)の役割を担うサービスです。

また`Git`には無い機能も追加されています。

特にプルリクエスト(Pull Request)は、ソースコードの変更点について
他のメンバーにレビュー依頼ができる機能で、レビューがOKとなった
ソースコードだけを反映させることができるので、品質の向上に役立ちます。

なお`GitHub`には無料と有料の2つのプランがあります。
無料プランではアップされたソースコード全てがGitHubの利用者に公開されてしまいます。

オープンなプロジェクトであれば、自分のソースコードについて他の技術者に助けてもらったり
逆に他の技術者を助けたりもできますが特別なプログラムを作っていた場合は
公開されてしまうのは都合が悪すぎます。

そう言った場合は有料プランに切り替えるか`Git`サーバーを自前で用意することになります。



## リポジトリ(repository)について

Gitでは`リポジトリ`という概念があります。
`リポジトリ`とはファイルやディレクトリの状態を記録する場所のことです

Gitの`リポジトリ`は`リモートリポジトリ`と`ローカルリポジトリ`の2種類に分けられます。

**リモートリポジトリ**
専用のサーバなどに配置して複数人で共有するためのリポジトリです。

**ローカルリポジトリ**
ユーザが個々に利用するために、自分のPC上に配置するリポジトリです。

`リポジトリ`を`リモート`と`ローカル`の2種類に分けることで
普段の作業は`ローカルリポジトリ`を使って全て手元のマシン上で行うことができます。
自分の`ローカルリポジトリ`で作業した内容を公開したい時は
`リモートリポジトリ`にアップロードして公開します。

`リモートリポジトリ`から他の人の作業内容を取得することもできます。

![alt](https://backlog.com/ja/git-tutorial/assets/img/intro/intro2_2.png)

参考：
https://backlog.com/ja/git-tutorial/intro/02/

## Gitの作業の流れ

まず開発を始める手順としては

**リモートリポジトリをクローンする**

**新しいリポジトリを作成する**

になるかと思います。
既に開発が進んでいるものに参加する場合は`リモートリポジトリをクローン`

これから新規で開発を進めていこうとする場合は`新しいリポジトリを作成する`
という手順をとります。

改めて1から作る場合の手順としては

1.リポジトリを作成する
2.ソースコードの作成、編集を行う
3.新規作成、変更、削除をGitのインデックスに追加する
4.インデックスに追加された内容をローカルリポジトリに登録(コミット)する
5.ローカルリポジトリの内容をリモートリポジトリに送信(プッシュ)する
6.他の開発者の差分をリモートからローカルリポジトリに持ってくる(プル)

と言う手順になります。

まずローカルとリモートリポジトリの概念は前項で把握しておいてください。
最初は何もない状態から自分のPCでプログラム等を作成したら
まずはそれらをローカルに登録することから始まります。

最初にローカルリポジトリに記録したいファイルをインデックスに登録を行います。
次にインデックスに登録したファイルをローカルリポジトリに登録を行い
この登録することをコミット(commit)と言っています。

ローカルリポジトリにコミットできたらリモートリポジトリの方にこの内容を送ります。
このことをプッシュ(push)と言っています。

![alt](https://backlog.com/ja/git-tutorial/assets/img/intro/intro4_1.png)

参考：
https://backlog.com/ja/git-tutorial/intro/04/

既に他の開発者が開発済みのファイルをリモートに登録していたら
その差分をローカルリポジトリに持ってきます。
このことをプル(pull)と言います。

慣れるまではややこしいですがこのような手順を繰り返しながら
開発を進めていくわけです。

お初の言葉がたくさん出てきますので次項で用語をまとめてみたいと思います。

## Gitの用語について
ここで今後良く使うGit用語についてやっていきましょう。

| 用語名 | 英名 | 意味 |
|:--|:--|:--|
| リポジトリ | repository | 履歴管理を行う場所。 |
| リモートリポジトリ | remote repository | サーバーにあるリポジトリ。基本はベアリポジトリで運用される。 |
| ローカルリポジトリ | local repository | 自分のPCにあるリポジトリ。基本はノンベアリポジトリで運用される。 |
| ベアリポジトリ | bare repository | ワークツリーを持たず、チェックアウト、マージができないリポジトリ。 |
| ノンベアリポジトリ | non bare repository | ワークツリーを持ち、チェックアウト、マージができるリポジトリ。 |
| ワークツリー | work tree | 履歴管理を行いたいファイルがある場所。 |
| インデックス | index | コミットしたいファイル又はファイルの一部を登録するところ。 |
| ステージ | stage | ワークツリーからコミットしたいファイル又はファイルの一部をインデックスに登録すること。 |
| ハンク | hunk | 変更した範囲。 |
| コミット | commit | インデックスに登録してある変更対象をローカルリポジトリに反映すること。 |
| リセット | reset | コミット前の変更をローカルリポジトリの状態へ戻すこと。また、特定のコミットまで状態を戻すこと。ただし、ローカルリポジトリに限られる。 |
| ヘッド | head | 作業対象となっているブランチ、コミット。 |
| チェックアウト | checkout | ヘッドを切り替えること。過去のコミットをチェックアウトしたらそれをもとにコミットすることはできない。 |
| プッシュ | push | ローカルリポジトリの変更をリモートリポジトリに反映させること。 |
| プル | pull | リモートリポジトリの変更をローカルリポジトリに反映させること。フェッチ＋マージ |
| フェッチ | fetch | リモートリポジトリの最新の履歴の取得だけを行う |
| マージ | merge | 異なるブランチの変更を反映させること。お互いの変更履歴が残る。 |
| リベース | rebase | 異なるブランチの変更を反映させること。変更履歴が片方に集約される。 |
| コンフリクト | conflict | マージ対象の２ファイルで同じ箇所が変更されており、自動でマージができないこと。 |
| ブランチ | branch | 履歴管理を枝分かれさせてたもの。ブランチを使うことで複数の履歴を並列に管理できる。 |
| フォーク | fork | リモートリポジトリをコピーしてリモートリポジトリを作成すること。 |
| クローン | clone | リモートリポジトリをコピーしてローカルリポジトリを作成すること。 |
| プルリクエスト | pull request | リポジトリでの変更を、フォーク元のリポジトリへ反映するよう依頼すること。 |
| ギットイグノア | .gitignore | 履歴管理の対象外とするファイルを登録するところ。対象範囲は各リポジトリ。 |


## まとめ

GitやGitHubは現在の開発では欠かすことができない物です。
Gitに関するおおまかな概念を抑えておきましょう。


君がエンジニアになるまであと47日

## 作者の情報
乙pyのHP：
http://www.otupy.net/

Youtube：
https://www.youtube.com/channel/UCaT7xpeq8n1G_HcJKKSOXMw

Twitter：
https://twitter.com/otupython