Git初心者のための、Git管理の考え方 ～童話「桃太郎」をGitで共同編集して完成させよう～

# はじめに
ソースコード管理のために広く使われている「Git」ですが、初心者にはとっつきにくいもの。今回は、私が本当に初心者理解に苦しんだ Gitでの管理の概念について、当時の私に向けて記事にしてみました。

その名も...
**童話「桃太郎」をGitで共同編集して完成させよう**

# 0. プロローグ
ある日、童話編集サークルにサークル会長から以下のミッションが降ってきました。
**童話「桃太郎」を、サークル内で手分けして完成さてほしい。**

サークル会長がもってきたプロットは以下のものです。
```
■ 第一部
昔々、あるところに、おじいさん と おばあさん が住んでいました。
ある日、二人は大きな桃を見つけ、それを割ると、中から赤ちゃんが出てきました。
二人は、赤ちゃんに「桃太郎」と名付けました。

■ 第二部
桃太郎は大きくなり、鬼退治に向かいました。
鬼の住む鬼ヶ島に向かう途中で、犬・猿・雉 を仲間にしました。

■ 第三部
鬼との闘いの末、桃太郎が勝ちました。
鬼から財宝を渡され、それを持って、おじいさん と おばあさん のもとへ帰ってきました。
```

# 1. さっそく共同編集へ
童話編集サークルには、A・B・Cさんの３名が所属していました。
サークル会長の持ってきたプロットを、以下のように分担して共同編集しようと考えました。
- 第一部 : Aさん
- 第二部 : Bさん
- 第三部 : Cさん

今回の共同作業では A・B・Cさんそれぞれ、ある程度の形になったら、その時点で会長のレビューをお願いすることにしました。会長からOKが出たら、晴れて、その編集分は完了です。

ここで「せっかく共同編集するなら、Gitを使ってみよう」という誰かの提案で、Gitで作業することになりました。

# 2. 共同作業の準備
まずは、momotaro というリポジトリを作成し、そこのmainブランチに、会長からもらったプロットを登録しました。この main ブランチには、会長のOKが出た内容だけを登録していきます。

ここからは、この童話編集サークルの Git奮闘記を見てみましょう。

# 3. 編集開始

## 3-1. １日目
まずは、A・B・Cさん、それぞれ自身のPCで編集作業をするため、 main ブランチに登録されている会長のプロットをダウンロードしてきました。
``` git clone https://*******/momotaro.git ```

そして、他のメンバーと作業がかち合わないようにするため、自分専用のブランチを作成します。
``` git switch -c feature/momotaro(メンバー名) ```

この日は、第一部を担当するAさんだけ作業がキリよく終わりました。こんな感じです。
```diff_markdown
■ 第一部
昔々、あるところに、おじいさん と おばあさん が住んでいました。
- ある日、二人は大きな桃を見つけ、それを割ると、中から赤ちゃんが出てきました。
+ ある日、おばあさん が 川へ洗濯しに行ったところ、川から大きな桃が流れてきました。
+ おばあさんは見つけた桃を家へ持ち帰りました。
+ 家で、おじいさんと一緒に、桃を大きな包丁で割ると、中から赤ちゃんが出てきました。
二人は、赤ちゃんに「桃太郎」と名付けました。

（以降、省略）
```

運の悪いことに、夜になってAさん自宅のネット回線が繋がりづらくなってしまいました。
しかし、Gitではインターネットがなくてもログを残しておくことができます。
Aさんは、翌日になっても自身の編集した箇所がわかるようにログを残すことにしました。
``` git add . ```
``` git commit -m "第一部：おじいさん と おばあさん の行動を具体的にしました" ```

これで、１日目のAさんの作業内容は記録されました。ネット回線の問題があり、git pushまではできませんでした。


## 3-2. ２日目
### Aさん
Aさんは、この日も以下の形でキリよく作業が終えられました。こんな感じです。
```diff_markdown
■ 第一部
昔々、あるところに、おじいさん と おばあさん が住んでいました。
- ある日、おばあさん が 川へ洗濯しに行ったところ、川から大きな桃が流れてきました。
+ ある日、おばあさん が 川へ洗濯しに行ったところ、川から大きな桃が どんぶらこ どんぶらこ と流れてきました。
おばあさんは見つけた桃を家へ持ち帰りました。
- 家で、おじいさんと一緒に、桃を大きな包丁で割ると、中から赤ちゃんが出てきました。
+ 家で、おじいさんと一緒に、桃を大きな包丁で スパッ と割ると、中から おぎゃー おぎゃー と赤ちゃんが出てきました。
二人は、赤ちゃんに「桃太郎」と名付けました。

（以降、省略）
```
しかし、まだAさん宅はネット回線が復調せず、今回もログだけ残しておくことにしました。
``` git add . ```
``` git commit -m "第一部：全体的に擬音語・擬態語を入れて修飾しました" ```

### Bさん
実はこの日、Bさんもキリよく作業が終えられました。
```diff_markdown
（以前、省略）

■ 第二部
- 桃太郎は大きくなり、鬼退治に向かいました。
+ 桃太郎は、とても逞しく育ちました。
+ そして、おばあさんに作ってもらった きびだんご を持って、村を苦しめている鬼の退治に向かいました。

- 鬼の住む鬼ヶ島に向かう途中で、犬・猿・雉 を仲間にしました。
+ 桃太郎の向かう先は、鬼の住む鬼ヶ島。
+ そこへ向かう途中、きびだんご が欲しいと話しかけてきた犬・猿・雉を仲間にしました。

（以降、省略）
```

Bさんは、ネットの不調もなく、ログを残すと同時に最近調子の悪いPCを心配して、リモートブランチにも編集内容を反映させておくことにしました。
``` git add . ```
``` git commit -m "第二部：桃太郎が鬼退治に向かっている時の具体的な状況説明を追加" ```
``` git push ```

そして、Bさんは今回の変更内容を、サークル会長にレビューしてもらうことにしました。
ここで、main ブランチへの Pull Request を出し、サークル会長にレビューを依頼します。
サークル会長が、Bさんの出した Pull Request の内容を確認して承認（approve）したら、現在は会長から出された一番最初のプロットの内容しかない main ブランチに、Bさんの編集内容が反映されます。

## 3-3. ３日目
まずは朝、会長はBさんからの Pull Requestに気づきました。
内容を確認したところ、問題なさそうだったため、Pull Request を Approveしたうえで main ブランチへ Mergeします。
この merge により、 main ブランチはこのようになりました。
```
■ 第一部
昔々、あるところに、おじいさん と おばあさん が住んでいました。
ある日、二人は大きな桃を見つけ、それを割ると、中から赤ちゃんが出てきました。
二人は、赤ちゃんに「桃太郎」と名付けました。

■ 第二部
桃太郎は、とても逞しく育ちました。
そして、おばあさんに作ってもらった きびだんご を持って、村を苦しめている鬼の退治に向かいました。
桃太郎の向かう先は、鬼の住む鬼ヶ島。
そこへ向かう途中、きびだんご が欲しいと話しかけてきた犬・猿・雉を仲間にしました。

■ 第三部
鬼との闘いの末、桃太郎が勝ちました。
鬼から財宝を渡され、それを持って、おじいさん と おばあさん のもとへ帰ってきました。
```

### Aさん
会長が、Bさんの変更を main ブランチへ merge した数時間後、やっと Aさん自宅のネット回線が復活。Aさんは急いで、自分のPCに保存していた編集内容をリモートブランチに push しました。
``` git push ```

そして、main ブランチへの Pull Request を作成します。

※git push というコマンドは一回実行するだけで、それまで commit した以下の両方の変更がリモートブランチへ反映されます。
- おじいさん と おばあさん の行動を具体的にしました
- 全体的に擬音語・擬態語を入れて修飾しました


## 3-4. ４日目
朝、会長はAさんからの Pull Requestに気づき、内容に問題ないことを判断して 承認（Approve）して main ブランチへ merge しました。
この merge により、 main ブランチはこのようになりました。
```
■ 第一部
昔々、あるところに、おじいさん と おばあさん が住んでいました。
ある日、おばあさん が 川へ洗濯しに行ったところ、川から大きな桃が どんぶらこ どんぶらこ と流れてきました。
おばあさんは見つけた桃を家へ持ち帰りました。
家で、おじいさんと一緒に、桃を大きな包丁で スパッ と割ると、中から おぎゃー おぎゃー と赤ちゃんが出てきました。
二人は、赤ちゃんに「桃太郎」と名付けました。

■ 第二部
桃太郎は、とても逞しく育ちました。
そして、おばあさんに作ってもらった きびだんご を持って、村を苦しめている鬼の退治に向かいました。
桃太郎の向かう先は、鬼の住む鬼ヶ島。
そこへ向かう途中、きびだんご が欲しいと話しかけてきた犬・猿・雉を仲間にしました。

■ 第三部
鬼との闘いの末、桃太郎が勝ちました。
鬼から財宝を渡され、それを持って、おじいさん と おばあさん のもとへ帰ってきました。
```

会長は、かなり形になった「桃太郎」に満足しつつ、これまでの編集履歴を確認します。すると、こんな内容を見ることができました。（見やすいように表形式にデフォルメしています。）
| 変更日 | 変更者 | 変更内容 |
|:-----------|:-----------|:------------|
| 1日前 | Bさん | 第二部：桃太郎が鬼退治に向かっている時の具体的な状況説明を追加 |
| 5分前 | Aさん | 第一部：おじいさん と おばあさん の行動を具体的にしました <br> 第一部：全体的に擬音語・擬態語を入れて修飾しました |

ここで、会長が気づきました。
「Cさん担当の第三部、まったく手がついていないぞ......:japanese_ogre::japanese_ogre::japanese_ogre:」
（commit 時のメッセージをちゃんとわかりやすく記載していると、こういう時にも役に立ちますね。）


# あとがき
以上、ここからは童話編集サークルで、Cさんの進捗確認と第三部の編集祭りが開催されたと思うのですが、長いので割愛します。

今回のアドベントカレンダー、題材どうしようかなと悩んでいました。
アドベントカレンダーというからには、誰かへの贈り物になりうるものだと良いなと。
そこで今回も、過去の自分に向けて、Gitの初歩を理解するための記事をかいてみることにしました。

書こうと思ったきっかけは、自身が初めてGitに触れたときの「なぜ、こんな小難しい概念を使っているんだろう…」という感覚を思い出したことでした。特に、commit と push の２段階（add や merge まで入れると4段階）ある必要性が、当時は理解できませんでした。

そこで、今回は非エンジニアの方や私と同じGit初心者の方向けに、あえて「コード以外のものをGit管理してみる」というテーマで
- commit
- push

の２段階あることの利点の一つに焦点を当てながら、整理をしてみました。
どなたかの参考になれば、うれしいです！
そして、もっと「こんな風に書けば、もっとわかりやすいよ」みたいなアイディアや、ここはちょっと間違いあるよ、みたいなご指摘あればぜひお願いします。