エンジニア以外が覚える Git のはなし

## まえがき
こんばんは！フロントエンド勉強中の nanarya です。
今回は、同僚のディレクターに、「 Git ってなんだかよくわからない」って言われてしまったので
非エンジニア向けとして Git について書いてみました。
私自身経験が浅いところもあるので、もし読んでいて分かりづらいところやお気づきのところがあればコメントにて指摘いただければと思います。
ベテランの方々からのご指摘もお待ちしてます。ぜひ勉強させてください！
あと、多分 Qiita 読んでる人ってエンジニアばかりだと思うので、この記事読む価値あるなって思ったら同僚の「 Git ってなんだかよくわからない」って言ってそうなディレクターや PM さんに紹介してあげてください。

## はじめに
このテキストは、非エンジニア（主にディレクター）向けに、 Git でどんなことができるかを書いたものです。

__実際に Git は使用しないが、 Git を使用したプロジェクトに関わっている__ という人が、
__Git を使うと何ができて、どう便利なのか__ を学べる内容となっています。
__Git の使い方はこれを読んでもわからないのでご注意ください。__

Git がわかると今後のプロジェクト運用でも流れの理解や効率化がしやすくなると思います。
今回は、オープンソース等ではなく、業務で使用するイメージでの説明ですので、リモートリポジトリが1つのパターンで説明します。
複数リモートリポジトリを持つようなパターンで業務されている場合もあるようでしたら追記します。

### この文章の目標
- Git の概要を理解する
- Git でのバージョン管理の仕組みを理解する
- Git でできること・できないことを理解する
- ~~Git が使えるようになる~~  
=> 非エンジニア向けなので、導入・使用方法等には詳しく触れません。

### ざっくりとした目次
- Git とは
- 用語解説
- Git についての詳しい話
- Git の操作や挙動についての話（メインコンテンツ）
- Git ホスティングサービスのはなし

といった感じの構成になっています。

## Git とは
Git（ぎっと）は、バージョン管理システムです。
制作過程をセーブデータのように保存しておくことができます。
バージョン管理システムは Git のほかにも多数ありますが、その中で現在の主流となっているのが Git です。
Git を管理・共有するためのサービス（ホスティングサービス）として、 GitLab , GitHub ,  Bitbucket などがあります。
わかりやすく言えば Git 用のクラウドサービスです。

## 用語解説
詳しい話に入る前に用語解説をしておきましょう。
もちろん他にも沢山用語はありますが、そのへんはエンジニア（使う人）だけが覚えていれば良いものです。
ここはすぐに全部覚えなくても良いので、読んでいてわからなくなったら戻ってきてみてください。
一昔前のゲームに例えるとこんな感じです。

|用語|分類|解説|
|---|---|---|
|リポジトリ|名詞|メモリーカード|
|ブランチ|名詞|セーブデータ|
|コミット|名詞/操作|セーブ|
|プッシュ|操作|セーブデータのアップロード|
|プル|操作|セーブデータのダウンロード|
|マージ|操作|取り込み|
|コンフリクト|事象|セーブの衝突|
|develop|ブランチ名|開発の中心になるブランチ|
|master|ブランチ名|現在公開されているものと全く同じ状態のブランチ|

- `リポジトリ` はメモリーカードに相当します。セーブデータを保存しておく場所です。リモートリポジトリ（クラウド）/ローカルリポジトリ（PC内）などがあります。  
- `ブランチ` はセーブデータです。更新するのはもちろん、コピーしたり、複数作って別の開発を進めたりもできます。
- `コミット` はセーブです。過去にセーブしたところまで戻ることもできるので、こまめにセーブしましょう。
- `プッシュ` はセーブデータのアップロードです。ローカルリポジトリの内容をリモートリポジトリに反映します。
- `プル` はセーブデータのダウンロードです。リモートリポジトリの内容をローカルリポジトリに反映します。
- `マージ` は取り込みです。少し特殊な概念なので詳しくは後述します。
- `コンフリクト` セーブデータの衝突（？）です。意味がわかりませんね。これはマージが理解できないとわからないので、これも後述です。
- `develop` や `master` はブランチにつける名前です。この名前でなくても良いのですが、みんなこの名前が大好きです。

> この案件の `リポジトリ` を `プル` したあと `develop` から `ブランチ` を切って、更新作業が終わったら `コミット` して `develop` に `マージ` してから `プッシュ` してください。確認できたら最後に `master` に `develop` を `マージ` してください。  

を言い換えると

> この案件の `メモリーカード` を `ダウンロード` したあと `developという名前のセーブデータ` から `セーブデータ` を切って（コピーを作って）、更新作業が終わったら `セーブ` して `developという名前のセーブデータ` に `取り込み` してから `アップロード` してください。確認できたら最後に `masterという名前のセーブデータ` に `developという名前のセーブデータ` を `取り込み` してください。

という感じです。用語を並べるために書いたので、実際にこんな指示は出ないと思います、多分。

## Git についての詳しい話
この項目では、Git とはどういうものかなど、概念的な話をします。

### バージョン管理システム
冒頭で `Git は、バージョン管理システムです。`と書きましたが、バージョン管理システムについて詳しく説明します。
通常、データは上書きしてしまうと前のものは消えてしまいます。
そのため、履歴を残していくためには、データの名前に日付をつけて残すなどの方法がとられることが多いです。

構成書\_完成版.xlsx
構成書\_完成版\_fix.xlsx
構成書\_完成版\_fix\_final.xlsx

バージョン管理システムはそういった手間を解決するシステムです。
（ただ、 Excel データは Git では管理できません）
Git を使うと変更が履歴として残るため、

- 過去にどういった変更を行なったのかを知ることができる
- 過去の状態に戻すことができる
- 過去の作業をなかったことにできる

などの利点があります。
特に文字データ（プログラムなど）と相性が良いため、使用者はエンジニアが中心です。  

### 分散型バージョン管理システム
Git はバージョン管理システムの中でも `分散型` バージョン管理システムと呼ばれるものになります。
集中型と分散型があり、それぞれの違いはリポジトリをいくつ作れるか、というところです。
集中型は１つ、分散型は複数のリポジトリを作ることができます。
Git は `分散型` なので複数のリポジトリを作ってバージョン管理をしていきます。

- 大元となるリモートリポジトリ（ネットワーク上にあるもの。GitHub 等のホスティングサービス(クラウド)を使用）
- 開発者Aのローカルリポジトリ（開発者AのPC上に存在）
- 開発者Bのローカルリポジトリ（開発者BのPC上に存在）

といった感じで複数のリポジトリを持ちます。
開発者A/Bは、自分のローカルリポジトリで制作をし、それをリモートリポジトリにアップロードすることで全体をアップデートしていきます。

## Git の操作や挙動についての話
ここでは、実際の操作やできることを説明していきます。

### リポジトリとコミット
まずはシンプルに1つのローカルリポジトリがある状態で、コミットをすることを考えてみましょう。
ここでは`リポジトリ` は Git 管理されたフォルダのことだと思ってください。
project_x というフォルダを Git 管理する（やり方は書きません）と、そこが project_x のリポジトリになります。

ローカルに `リポジトリ` （Git 管理されているフォルダ）があるので、 project_x 以下のディレクトリはすべて Git に監視されることになります。  

```
project_x
├── text1.txt
├── text2.txt
└── text3.txt
```

この中の text1-3.txt はすべて Git の管理対象です。
たとえばこの中から text1.txt を修正したとします。

```text1.txt
おはよう
こんにちは
こんばんは
```

これを

```text1.txt
おはよう
こんにちは
ごきげんよう
```

このように変更すると、 Git は `text1.txt の 3行目が変更された` と読み取ってくれます。
<img width="296" alt="スクリーンショット 2018-08-20 23.29.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/251512/001c1b8f-3f91-6d4e-3894-29a77795fe14.png">

ただし、変更しただけでは履歴は残りません。そう、セーブが必要です。
そのセーブ動作が `コミット` と呼ばれるものです。
`コミット` にはコメントすることができるので `こんばんはをごきげんように変更` といったように変更内容を残すことができます。
このコミットを積み上げていくことで、履歴を残しながら開発を進めることができます。
過去のコミットに戻ったりすることもできるため、こまめにコミットしていくことで、開発が快適に進んでいきます。


### ブランチ　〜セーブデータを分ける
先ほどの例だと、常に上書きしていくだけなので、履歴が残るだけですが、ブランチ（セーブデータ）をコピーして別の作業をしていくこともできます。
リポジトリを作ると `master` という名前のブランチが1つだけあることが多いため、これをコピーして `develop` というブランチを作ります。
ちなみにこのブランチを作る作業を `ブランチを切る` と表現します。
これで `master` と `develop` 全く同じブランチができます。
中身を確認するとこうなっています。

```(master)
project_x
├── text1.txt
├── text2.txt
└── text3.txt
```

```(develop)
project_x
├── text1.txt
├── text2.txt
└── text3.txt
```

コピーなので、当然全く同じ中身です。  
<img width="426" alt="スクリーンショット 2018-08-20 23.28.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/251512/60b18fe6-9b6b-1d94-18d8-27cd1454841b.png">
ブランチは Git におけるセーブデータなんですが、これは実際に中身のデータが複数存在しているわけではなく、Git 上でのみ存在する概念のようなものだと思ってください。
さて、ブランチが　`master` と `develop` で2つのブランチができたので、これを片方だけ進めてみましょう。
`develop` の中の `text1.txt` を先ほどのように修正してみましょう。

```text1.txt(develop)
おはよう
こんにちは
ごきげんよう
```

一方その頃 `master` のほうを見てみるとどうなっているかというと

```text1.txt(master)
おはよう
こんにちは
こんばんは
```

`こんばんは` のまま変わっていません。
別のセーブデータなので、当然ですね。
<img width="416" alt="スクリーンショット 2018-08-20 23.30.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/251512/7e16ee9a-102e-20ad-1ac7-6cd68e4d8807.png">

こうやって並行して `状態の保持` や `別の開発` をすることができます。
ブランチは切り替えることができるので、いつでも `develop（ごきげんよう）` と `master(こんばんは)` を行き来できます。

#### これができると何が便利？
> こうやって並行して `状態の保持` や `別の開発` をすることができます。  

と書きましたが、これができると何が便利か。  

まずは `状態の保持` について。  
ブランチを分けると `master` `develop` など名前をつけてパラレルで運用していくことになります。
こういった場合、大抵 `master` は公開中のものと同じ状態を保持し、 `develop` で更新作業をします。更新作業が完了したら `master` にマージ（後述）します。そうすることで、 `master` は常に公開中のものと同じ状態で保持しておくことができます。

もうひとつ、 `別の開発` について。
これは全く別の開発を行うということではなくて、あくまで2つの機能を拡張していく、といったような意味合いでとらえてください。 git がないと機能Aと機能Bを同時に実装していくのは、非常に難しいです。もちろん、公開が同じタイミングであれば最終的に合わされば良いのでなんとかなりますが...
先行公開の機能Aの作業中に、開発期間の長い機能Bの作業を進めておきたい場合、機能Aを公開するタイミングでは開発中の機能Bの作業は全く反映されないようにしなくてはなりません。そういった際にブランチを分けておくと、お互いの作業内容に干渉せずに開発していくことができるわけです。

#### 実際のブランチの使い方
実際は `master` `develop` の2つではなく、もっと複雑にブランチを用意するため、そのあたりを簡単に説明していきます。

ブランチは基本的に数に制限はないので、必要に応じて適した名前のブランチを作っていくことになります。よくある例ではこんな感じでしょうか。

|ブランチ名|内容|
|---|---|
|master|公開中のものと同じ状態|
|develop|開発の大元になるもの。このブランチで直接作業はしない|
|feature/#3-xxx|`xxx`を実装中。名前は実際のところ自由ですが、feature というディレクトリで区切ることが多いです。`#3` は Issue （後述）の番号、`xxx` は適当に開発内容を入れます。|
|feature/#5-yyy|同上|

こういった感じで作っていくことが多い印象です。
ほかにはテストアップ時用の `test` やバグフィックス用の `hotfix` なんてものを作ったりもしますね。
これも明確に決まっているものがあるわけではなく、日々最良のブランチの切り方が研究されてます。
なので、現場によっては全く違う使われ方がしているかもしれませんね。

上の例の場合は
`develop` から `feature/xxx` などを切って作業をし、作業完了後に `develop` にマージ。公開に合わせて `develop` を `master` にマージ。という流れですね。

例えば `feature/**` でブランチを切って作業して見ると...
<img width="441" alt="スクリーンショット 2018-08-20 23.35.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/251512/b0ad3405-9e84-72c6-df5d-4eba4a299835.png">
こんな感じで進んで行って、
<img width="518" alt="スクリーンショット 2018-08-20 23.37.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/251512/573b9321-f8e8-7e1e-672c-cce0fecef797.png">
最終的に合流したり、また枝分かれしたりしていきます。

### コミット　〜物語をセーブする
リポジトリやブランチなどの大枠の仕組みがわかってきたところで、実際の作業に伴う一番基本的操作、コミットについて覚えましょう。

コミットはゲームで言うところのセーブに当たります。が、ただのセーブではなく、ちょっと便利なセーブなんです。まずはどこが便利なのかを見ていきましょう。

#### コミットは差分を覚えておける
コミットはえらいので、セーブ前の情報も覚えててくれます。先ほどの挨拶のtxtを例にとると、「 `こんばんは` を消して `ごきげんよう` を追加した」というところまで覚えててくれます。なので、その時のセーブでどんなことを行なったかが一目でわかります。

#### コミットは前のセーブに戻ることができる
コミットはえらいので、セーブの履歴も覚えててくれます。ひたすら上書きしていくだけではなく、履歴を取りながらセーブを重ねてくれるため、昔のコミットに戻ることができます。3回前のセーブに戻りたい！というゲームでは叶わない願いを、コミットは叶えてくれるのです。

#### コミットにはコメントを入れることができる
コミットはえらいので、コメントを入れることができます。複数人での作業の際や、備忘録として活躍します。なぜこんな編集を行なったのか、などが残っていると後々役立ちますね。

#### コミットはこまめに
コミットはえらいので、色々と便利なんですが、1つだけ問題があります。コミット単位でしか履歴を残せないことです。10日分の作業が1つのコミットにまとまっていると、3日前の状態に戻すことはできません。なので、コミットはこまめに。RPGでもこまめなセーブは大切ですね。

### プルとプッシュ　～ダウンロードとアップロード
次はプッシュとプルについてです。
といっても、ダウンロードとアップロードという概念がとてもわかり易いので、あまり説明はいらないですかね？

- リモートリポジトリの状態をローカルリポジトリに反映させること（プル）
- ローカルリポジトリ（PC内）で作業したものを、リモートリポジトリに反映させること（プッシュ）

それぞれこんな感じです。
プッシュやプルはブランチ単位で行われます。
なので、プッシュしたときに `手元で試しに作ったテスト用のブランチ`が、勝手にアップロードされてしまう、というようなことは基本的にはありません。

### マージ　～取り込み
マージはちょっと難しい概念なので、色々と後回しにしていましたが、コミットとブランチがしっかり理解できた方にはすぐに飲み込めるんじゃないかと思います。
マージは取り込みです。`feature/xxx` を `develop` に__マージする__、というような使い方をします。

`feature/xxx` はもともと `develop` からブランチを切っている（コピーしている）ので、最初は同じデータ群です。
そこから `feature/xxx` に変更を加えると、 `develop` より一歩進んだデータ群になります。もちろん、そのままだと別個のブランチとして別々の道を歩んでばかりです。
そこで、 `feature/xxx` での作業が終わったあと、その作業を大元に反映させるため、 `develop` にマージします。マージを行うと、 `feature/xxx` に残されたコミットの情報を元に、 `develop` との差分を確認し、更新してくれます。

これで `develop` は `feature/xxx` で行なった編集も反映された状況になるわけです。

#### マージリクエスト（プルリクエストともいう。以下マージリクエストで統一）
さて、新しい単語が突然出てきました。__マージリクエスト__です。
名前を見ればなんとなく察しがつくかもしれませんが、マージしてください、というリクエストのことです。
開発は複数人で行うことが多いので、勝手にマージしてどんどん新しくしていくのではなく、__ワンクッション置く__ことも大切です。
そこで活躍するのがこのマージリクエスト。
マージしてください、と他の人に通知することで、コードレビュー（他の人のチェック）などを行うことができます。
この機能のおかげで__みんなの同意の上で更新していくことができる__、というわけですね。
ちなみに、使っているホスティングサービス（GitHub や GitLab）によって用語が変わりますが、意味としては一緒だと思って大丈夫です。説明しやすいのでマージリクエストで書きました。

#### コンフリクト
あ～、起きちゃったか、コンフリクト。困ったな～。
コンフリクトは、マージの際に2つのブランチで同じ箇所を修正していた場合に発生します。
要は__同じところを修正してるからどっちを優先すべきかわからないよ！__ってなっている状態です。
これが発生してしまった場合は、状況を確認して、どちらを優先させるか見極めた上で解決する必要があります。
Git はとっても便利ですが、適当に使っているとこういった面倒なことが起きたりするので、ちゃんと考えて運用しましょうね。

## Git ホスティングサービスのはなし
さて、 Git の基本的な話が終わりましたので、ついでにホスティングサービスの話をしておきましょう。
GitHub や GitLab のことですね。
エンジニア意外の人はこちらのほうが馴染みが深いかもしれませんね。
この GitHub などは、__Git をチーム内で共有するためのクラウドサービス__だと考えてください。
Git のリポジトリ（に含まれるブランチやコミットなども）を保存しておくサーバーです。
ただ、データを置いておくただのサーバーというわけではありません。
Git に付随した様々な機能が提供されています。

### Issue
代表的なものがこの Issue です。
有り体に言ってしまえば、掲示板です。
ただ、コミットのコメントなどから Issue 番号（掲示板 ID のようなもの）を指定すると連携されるなど、Git との連動性は抜群です！
マークダウンと呼ばれる方法で簡単な修飾が可能だったりするため、チャットなどよりもわかりやすい文章を書くことができます。（ちなみにこの文章もそのマークダウンで書かれています。）

### Wiki
こちらも案件の情報をまとめておくのに有力な機能です。
こちらは Wikipedia を想像してもらえればよいかと思います。
情報をまとめておくことができ、かつ更新をすることができます。

### そのほかにも
ほかにも、先程書いたリポジトリ / ブランチ / コミットの情報を見ることができたり、ユーザーごとの更新頻度がわかったり、サービスによってさまざまな特徴があります。
お使いのホスティングサービスについて調べれば、沢山情報が出てくると思います。
（このあたりはエンジニア向けの記事を読んでも十分わかりやすくて価値があるかと思いますので今回は割愛します）
これらの機能を使いこなすことができれば、__案件の情報をすべて Git ホスティングサービスにまとめることができます__。
（※ただし、データの共有については別のシステムが必要です）
そうすることで、大量かつ煩雑な情報が、1つのWEBページからすべてたどれるようになります。
また、その案件に関わる全ての人に共有することができます。
これってとってもいいことだと思いませんか？

##おわりに
長々とお読みいただきましてありがとうございます。
Git って、やっぱりエンジニアが使うものなので、エンジニアが実際に使うための記事みたいなものが非常に多いんですよね。
なので、実際に使わない人向けの記事を書いてみたという感じです。
せっかくお読みいただいたので、ご意見ご感想お待ちしています。
間違いや、もっとこうしてほしいというようなことがあればコメントいただければ、できる範囲で加筆修正したいと思います。

それではみなさま、よい Git ライフを。