【初心者向け】Git・GitHub用語集

以下は
『筆者が現在参画している、GitHubを用いて開発を行っているプロジェクトへの新規参画者向け用語集』
です。

想定読者は「初めてGitに触れる」「当然GitHubを用いて開発を行うのも初めて」という人ですので、それに該当する学生さんなんかにも役に立つかと思い、記事として公開することにしました。
「gitは手順書に従って使ったことはあるけど、イマイチよくわかってない」という人にとっても参考になるかも知れません。

くどいくらいに文中リンクを用いていますが、その用語の意味や概念を理解していることを前提として説明していますので、「えーと、これってどういう意味だっけ…？」と思った瞬間にリンク先にジャンプして復習しながら読み進める作業を繰り返してください。
いずれも、筆者が参画しているプロジェクトでは必須となる知識です。

gitやGitHubといったツールの習得には時間が掛かるのは事実ですが、このような便利ツールの使い方がわからず手が止まるのは「電車に乗って会社に行って仕事しなきゃいけないけど、切符の買い方がわからなくて電車に乗れない」みたいな状態だと思います。
切符の買い方なんてのは本来やらなきゃいけない仕事以前の話であり、そんなものは自分で調べてどうにかすべきですので、この用語集やネット上の記事を読んで自分でリポジトリ作って実験して…どうにかして下さい(笑)

## Git
[バージョン管理システム](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)(版管理システム)の一種。
Webサービスである[GitHub](#github)とは別物。

Gitに関する基本用語を以下に列挙する。

### git
Gitを制御するコマンド。Windows機の場合はgit.exe、Un\*xであればgitという実行ファイルとほぼ同義。
当記事内では、これを指す場合は小文字でgitと表記し、Gitと区別して扱う。

### Gitクライアント
[各種gitコマンド](#gitコマンド)のwrapper。GUIのものが多い。
代表的なものは
- [Sourcetree](https://www.sourcetreeapp.com)
- [TortoiseGit](https://tortoisegit.org)
- [GitKraken](https://www.gitkraken.com)

辺りだが、近年はVSCodeやVisualStudioをGitクライアントとして利用するケースも多い模様。(筆者が現在参画しているプロジェクトも、基本的にVSCodeをGitクライアントとして利用する方針)

経験上、GUIクライアントのみに頼るとGitの理解が乏しくなり、トラブルシュートに対応しにくくなる印象がある。(もちろん、人や環境によるが。)
かと言って、gitのみならずCUIすらも初めてという『IT初心者』や、GUI開発環境のみで生きてきた『ベテランWindowsエンジニア』にCUIでのGit操作を強要するのも酷なので、
- 基本はGUIクライアント経由で操作しつつ、各操作の裏で発行されているgitコマンドを積極的に調べるよう努力する

という取り組み方が良いかと思う。

VSCodeを用いるのであれば、
- [GitLens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)
- [Git Graph](https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph)

辺りの拡張機能をインストールしておくとほぼGUIで完結できるはず。

ちなみに筆者自身はEmacs上で動作する[Magit](https://magit.vc)を愛用していたが、現在はVSCode上で[edamagit](https://github.com/kahole/edamagit)等の拡張機能を組み合わせて利用しつつ、足らずをコマンド直打ちで補っている。
(同僚の@masaminは現在もMagitのためだけに[Spacemacs](https://www.spacemacs.org/)を使っている模様…)

### 作業ツリー
作業対象となるディレクトリとファイル群。入れ子のツリー構造となっている。
以下も同義。
- ワーキングツリー(working tree)
- 作業ディレクトリ、ワーキングディレクトリ(working directory)

### インデックス
変更したファイル群のスナップショットを[commit](#commit)前に一時的に保存しておく領域。
commit対象となるのは、この領域に登録された内容。

ステージ(stage)と呼ぶことも多く、[add](#add)でインデックスに追加することをステージングと表現する。
「スナップショット(ある瞬間の切り抜き)」や「ステージ(撮影台)」は写真用語なので、変更履歴を保存する作業を写真撮影に喩えている模様。

### リポジトリ
ファイルの格納庫(repository)。[Git](#git)に於いては[作業ツリー](#作業ツリー)の最上位(ルート)ディレクトリを指す。
ここに「『[コミット](#コミット)』という単位で作業ツリーのスナップショットが変更履歴として格納されている」という理解で問題無い。
存在する場所によって、以下の2つに大別される。

#### リモートリポジトリ
ネットワーク上に存在し、複数の開発者で共有するリポジトリ。
当記事内では、インターネット上にあり[GitHub](#github)が管理するリポジトリを指す。
各種クラウドストレージと同様のイメージで捉えておけば良い。

#### ローカルリポジトリ
各開発者のコンピュータ内に存在するリポジトリ。
Gitは、[作業ツリー](#作業ツリー)のルートに「.git」というディレクトリを作成し、その配下に各種管理ファイルを配置することでそのディレクトリをリポジトリとして扱うため、「ルートに.gitディレクトリがあるローカルPC内のディレクトリ」と脳内変換しても差し支え無い。

当然ながら、ここでの作業内容は他の開発者には見えない。
他の開発者(自身の別PC含む)と共有するためには、[push](#push)して変更内容を[リモートリポジトリ](#リモートリポジトリ)に反映する必要がある。

### Gitオブジェクト
[Git](#git)は、管理対象のファイルやコミットを4種類の「オブジェクト」として`.git/objects`ディレクトリ内に保存している。
いずれもzlibライブラリで可逆圧縮されたものであり、コンテンツ(ファイル)の内容にヘッダーを加えたデータから生成した40文字のsha-1ハッシュ値で管理されている。
オブジェクトは、ハッシュ値の先頭2文字のディレクトリ内に残りの38文字のファイル名で保存される。
オブジェクトの内容は[cat-file](#cat-file)コマンドで表示することができる。

これらGitオブジェクトのうち、tagオブジェクト以外の3種類について説明する。
5334912124033467blobオブジェクト
リポジトリ内の各ファイルの中身そのもの。ファイル名は含まれない。
変更したファイルが[インデックス](#インデックス)に登録される度に新規に生成される。

#### treeオブジェクト
リポジトリ内の各ディレクトリの情報を保持している。
オブジェクトの中身は以下の通り。
- ディレクトリ直下に存在するファイル及びディレクトリの名前
- それらに対応するblobオブジェクト及びtreeオブジェクトのハッシュ値

生成されるタイミングについてはtreeオブジェクトが保持している内容を考えれば自明なので蛇足ではあるが、念のため記載しておく。
以下の内容が変化する度に新規に生成される。
- ディレクトリ直下のファイルの内容が変更されたことにより、そのファイルに対応するblobオブジェクトが更新された
- ディレクトリ直下に存在するファイルやディレクトリに対し、追加や削除(移動・リネーム含む)が行われた
- ディレクトリ直下に存在するディレクトリに対応するtreeオブジェクトが更新された

#### commitオブジェクト
所謂[コミット](#コミット)。これを作成する[commit](#commit)コマンドとは別物だがどちらも「コミット」と呼ばれるので、どちらを指しているのかを文脈に応じ判断する必要がある。
オブジェクトの中身は以下の通り。
- 作成時点のリポジトリルートディレクトリの[treeオブジェクト](#treeオブジェクト)
- commitオブジェクトの作成日時
- commitオブジェクトの作成者情報
- [コミットメッセージ](#コミットメッセージ)
- 親コミット(1つ前のコミット)のハッシュ
    - リポジトリ内の初回コミット(initial commit)には親コミットは存在しない
    - [マージコミット](#マージコミット)は親が2つある

### コミット
変更履歴のこと。実体は[commitオブジェクト](#commitオブジェクト)。[commit](#commit)や[rebase](#rebase)、[cherry-pick](#cherry-pick)等のコマンドによって作成される。

以下の情報を持っていることは頭に叩き込んでおくこと。
- コミットが作成された時点での[リポジトリ](#リポジトリ)のスナップショット
- 40文字のsha-1ハッシュ(コミットのID)
- 一つ前のコミット(親コミット)のハッシュ
- コミットの作成日時
- コミットの作成者情報
- [コミットメッセージ](#コミットメッセージ)

#### HEAD
[カレントブランチ](#カレントブランチ)の最新のコミットに対するポインタ。
[ブランチ名](#ブランチ)同様、「特定のコミットに貼る付箋」のようなイメージ。
[reset](#reset)でこれを別のコミットに貼り替えることで、結果としてブランチを巻き戻したり逆に進めたりすることができる。

実体は`.git/HEAD`というファイルで、内容は
```
ref: refs/heads/main
```
のように「[ブランチ](#ブランチ)の最新コミットを保持しているファイル名」となっており、Gitはこれを基に[カレントブランチ](#カレントブランチ)を判断する。(detached headという状態も存在するが、ここでは言及しない)
[switch](#switch)等の操作によりカレントブランチを切り替えた際は、HEADの内容がそれに合わせて書き換わる。
詳細は下図参照。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270699/01700ab9-1f9c-4a13-7fbd-5eefef17e309.png)
要は「『[commitオブジェクト](#commitオブジェクト)への参照である[ブランチ](#ブランチ)』への参照」である。
C/C++風に言うとダブルポインタ。

### コミットメッセージ
[コミット](#コミット)の内容を説明するメッセージ。[commit](#commit)時に作成する。
書き方について、[Git](#Git)の制約や規定は特に無いが、以下のような形式にするのが一般的である。
```
コミット内容の概要を一行で書く
[空白行]
コミット内容の詳細を書く
必要であれば複数行に亘って書いても良い
```
上記のような書き方をしておくと、[GitHub](#github)上や各種Gitクライアントツールでも下図のようにうまく表示される。

- GitHubでは空白行までがコミットのタイトルとして表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270699/549a4dd1-655a-02fb-4da4-935ca245266c.png "")
- 3点リーダーをクリックすると、空白行より下の部分が詳細メッセージとして展開される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270699/118b3580-9eff-374e-8f39-73d696655cbe.png)


### ブランチ
変更履歴を枝分かれさせて管理するために用いられる機能。

実際のところ、「ブランチ」は「[コミット](#コミット)に対するポインタ」でしかない。
具体的には`.git/refs/heads/`ディレクトリに保存されている各ブランチ名のファイル群。各ファイルの内容は、各ブランチの最新の[commitオブジェクト](#commitオブジェクト)のハッシュ値。

「ブランチ名は、特定のコミットに貼られた付箋のようなもの」ということを理解することが**極めて重要**。
その付箋は、基本的にそのブランチの先頭(最新)のコミットに貼られている。

「[reset](#reset)で別のブランチのコミットに移動したりブランチを巻き戻したりした場合も、実態としてはブランチ名が書かれた付箋を元のコミットからreset先のコミットに貼り替えているだけである」というイメージを持てるようになれば、各種gitコマンドへの恐怖感がグッと減る。

#### 存在場所による分類
ブランチの存在場所という観点から、以下の3つに大別される。

##### リモートブランチ
[リモートリポジトリ](#リモートリポジトリ)内に存在するブランチ(群)。
[GitHub](#github)の画面からブランチに対し何かしらの操作を行った場合、変更されるのはあくまでもリモートブランチであるため、[fetch](#fetch)等のコマンドを用いその変更内容を[ローカルリポジトリ](#ローカルリポジトリ)に取り込む必要がある。

##### リモート追跡ブランチ
[ローカルリポジトリ](#ローカルリポジトリ)内に存在し、リモートブランチの写像となるブランチ。
[fetch](#fetch)等のコマンドでリモートブランチでの変更内容を反映する以外は、基本的にこれらを直接変更することは無い。

##### ローカルブランチ
ローカルリポジトリ内に存在し、各開発者が直接変更を行うブランチ。
ここに対して変更を[commit](#commit)することで[コミット](#コミット)を作成し、そのコミットを[push](#push)することでリモート追跡ブランチ及びリモートブランチに変更を反映する。
なお、[GitHub](github)にとってのローカルブランチは開発者にとってのリモートブランチである。

#### 利用目的による分類
筆者が参画しているプロジェクトでの利用目的によって分類すると、以下の2つに大別される。

##### デフォルトブランチ
当記事が想定する開発スタイルでは、レビューを通過した正式版が格納されているブランチのことを指す。
昔は「master」という名称にするのが一般的だったが、master⇔slaveという表現がよろしくないとのことで2020年頃からは「main」という名称にする風潮となった。
参考：[The default branch for newly-created repositories is now main](https://github.blog/changelog/2020-10-01-the-default-branch-for-newly-created-repositories-is-now-main/)

##### featureブランチ
各機能の開発やバグの修正に用いられる、作業用の使い捨てブランチ。「機能ブランチ」や「トピックブランチ」と呼ばれることもある。

当記事が(略)では、各開発者は変更内容を[mainブランチ](#デフォルトブランチ)に[commit](#commit)するのではなく、基本的に下記の流れで作業を行う。
1. [Issue](#issue)を起票
1. そのIssueに関する作業を行うfeatureブランチを作成
1. 作成したfeatureブランチに変更をcommitし、[push](#push)
1. そのfeatureブランチをmainブランチに[merge](#merge)するための[Pull Rquest](#pull-request)を作成し、レビューを受ける
1. レビュー通過後、Pull Requestの機能を用いreviewerがmainにmergeし[リモートリポジトリ](#リモートリポジトリ)内のfeatureブランチを削除
1. 各開発者は`git fetch --prune`にてリモート追跡ブランチを削除し、[ローカルリポジトリ](#ローカルリポジトリ)内のfeatureブランチも削除

### カレントブランチ
現在、作業対象として選択されている[ローカルブランチ](#ローカルブランチ)のこと。
複数の[PR](#pull-request)の作業を並行する場合は、これを切り替えて対象となるブランチを都度変更しながら作業を進める。

### コミットグラフ
リポジトリ内の[コミット](#コミット)群をツリー状に並べて表示したもの。樹形図とも呼ぶ。
随時これを更新し確認しながら作業を進めるべきだが、以下の理由により初学者は無視しがちである。

1. 複雑な樹形図
  Git初心者であるほど[Gitクライアント](#Gitクライアント)に促されるまま[pull](#pull)や[merge](#merge)を多用するため、ブランチ間でのmergeが大量に発生し、それに伴う[マージコミット](#マージコミット)も作成される。
  その結果、線が入り乱れた複雑なグラフになる。
  これを追いかけるのは熟練者でも疲弊する作業なので、初心者が「わけわからん」と感じグラフを見なくなるのは至極当然である。
1. ブランチを区別しづらい
    大抵の[Gitクライアント](#gitクライアント)では、[リポジトリ](#リポジトリ)の変更履歴を表示した際に
    - [リモート追跡ブランチ](#リモート追跡ブランチ)と[ローカルブランチ](#ローカルブランチ)のどちらにも存在する[コミット](#コミット)は一つのものとして表示される
    - 片方にしか存在しないものは共通部分から枝分かれして表示される

    という挙動となるが、初心者がこれを見たときに
    - リモート追跡ブランチとローカルブランチは別物であること
    - [リモートブランチ](#リモートブランチ)とリモート追跡ブランチは別物であること(リモートブランチの内容が必ずしもリモート追跡ブランチに反映されているとは限らない)

    を整理して読み取ることは困難である。

1.については[rebase](#rebase)等を駆使しコミットが一直線に並ぶよう心掛けることで、2.については[ブランチの分類](#存在場所による分類)についてしっかり理解することで、それぞれ軽減できる。

いずれも、その辺りの理解が乏しい初心者がブランチを利用し複数名で開発した際に生じる問題なので、[Gitクライアント](#gitクライアント)の項で述べた通り、クライアントツールの操作方法の『丸暗記』と仕組みの『理解』を並行して行う必要がある。
時間と相談にはなるが、GitHub上に個人リポジトリを作成し実験する等の作業も積極的に行うべきである。

## gitコマンド
代表的なgitのサブコマンドを以下に列挙する。
なお、「gitのサブコマンド」を「gitコマンド」と表現するのが一般的なようなので、当記事でもそれに倣う。

### add
変更内容を[インデックス](#インデックス)に追加する。
変更したファイルを丸ごと追加するだけでなく、`-p`オプションを付与して実行することで変更箇所をハンクに分割しステージングする範囲を選択することも可能。

### commit
[インデックス](#インデックス)に登録された変更内容を[ローカルブランチ](#ローカルブランチ)に記録する。
この操作により、その時点でのスナップショットが[コミット](#コミット)として作成される。
[リモート追跡ブランチ](#リモート追跡ブランチ)及び[リモートブランチ](#リモートブランチ)は変更されない点に注意すること。

### push
[ローカルブランチ](#ローカルブランチ)の[コミット](#コミット)を[ローカル追跡ブランチ](#ローカル追跡ブランチ)及び[リモートブランチ](#リモートブランチ)に反映する。

#### 強制push
`git push --force-with-lease`(或いは`git push --force`)のように、強制実行するオプションを付与して[push](#push)を実行すること。

通常、pushを行う時点では
- [リモートブランチ](#リモートブランチ)に存在する[コミット](#コミット)は全て[ローカルブランチ](#ローカルブランチ)に存在する
- それらに加え、ローカルブランチにのみ存在する新しいコミットが存在する

という状態になっているはずで、後者が更新内容、すなわちpushする対象となっているはずである。[Git](#git)もこれを想定しており、この状態をpush可能な条件としている。
ところが、[rebase](#rebase)等のコマンドでローカルブランチのコミットを作り直すと前者の条件を満たせなくなり、Gitはこれを「ローカルがリモートより遅れている」と判断するため、この状態でpushするとエラーが発生し失敗する。(エラーメッセージ内で[pull](#pull)を促してくるのはこれが理由)
このように前者を満たさない状態のローカルブランチの内容をリモートブランチに反映すると、結果としてリモートブランチに存在したコミットが消失するため、これはある意味危険な操作である。
それを承知の上で実行するには、前述のオプションを付与してpushを行う必要がある。

二種類のオプションの挙動の差異についてはここでは言及しないが、ネット上に多数情報があるので各自調査すること。

### fetch
[リモートブランチ](#リモートブランチ)の変更内容を[リモート追跡ブランチ](#リモート追跡ブランチ)に反映する。
リモートブランチの先頭(ブランチ名が指すコミット)を取得し、そのコミットが保持している親コミットを取得し…という流れで順に取得することでコミットグラフが作成されるイメージ。
[GitHub](#github)上でリモートブランチに対して変更を行った場合や、他者がリモートブランチに[push](#push)した内容を取得する場合に使用する。
あくまでもリモート追跡ブランチを更新するコマンドであり、[ローカルブランチ](#ローカルブランチ)は変更されないことに注意。

### merge
別ブランチの内容を[カレントブランチ](カレントブランチ)に「合わせ込む」コマンド。
各ブランチの状態及びmergeの挙動に関する設定により、[マージコミット](#マージコミット)が作られるか否かが分かれる。
当記事が想定(略)では、[Pull Request](#pull-request)完了時にreviewerが[GitHub](#github)上で実行する以外に使用する機会は無い。

### pull
[fetch](#fetch)＋[merge](#merge)。
GUIの[Gitクライアント](#gitクライアント)はこれを実行するよう頻繁に促してくるが(特にVSCode/VisualStuidoは顕著)、当記事が(略)では、以下の理由により使用する機会はほぼ無い。

- ローカルのmainブランチは更新せず放置しておいて良い
  開発作業は都度[featureブランチ](#featureブランチ)を作成して行い、[mainブランチ](#デフォルトブランチ)へのmergeは[GitHub](#github)上で行うため、ローカルのmainブランチは更新する必要が無い。
  featureブランチを最新のmainに[rebase](#rebase)する等の作業を行う際は、[ローカル追跡ブランチ](#ローカル追跡ブランチ)のmainのみ[fetch](#fetch)して更新しておけば良い。
- featureブランチへのpullは不要
  featureブランチへのpullを促される場面として想定されるのは、[rebase](#rebase)等によりコミットを作り直した結果リモート追跡ブランチに存在するコミットがローカルブランチに存在しなくなった場合である。
  この状態をGitは「ローカルがリモートより遅れている」と判断しpullを促してくるが、ここでは意図的にこのような状態にしているのであって、当然ながらpullする必要は無い。(してはいけない)
  この場面で行うべきはpullではなく[強制push](#強制push)である。

pullする機会は以下のケース程度かと思われる。
- 正式版の最新バージョンを取得して動作確認する
  リモートのmainブランチの最新版を取得して動作確認することになるため、ローカルのmainブランチをリモートの最新まで進める必要がある。
- revieweeが修正した内容を確認する
  レビューの過程で、フィードバックの反映等の理由でrevieweeが変更をpushした場合、書面レビューで足りなければreviewerとしてfeatureブランチの最新版を取得して確認した方が良いことも多い。

上記いずれの場合もpullを使わずとも実現可能。

### reset
[HEAD](#head)が指すコミットを変更する。
「HEAD」という付箋を別のコミットに貼り替えるイメージ。
コミットを消すわけでは無いが、hard reset(`git reset --hard`)すると未commitの変更内容は失われるので注意。

### cherry pick
別ブランチの[コミット](#コミット)(での変更内容)を[カレントブランチ](#カレントブランチ)に適用する。

### rebase
(図を用いた説明を追記予定)

コミットの作り直しに慣れるためにも、まずは
1. 新規ブランチを作成し、featureブランチの内容を退避
1. featureブランチをmainの最新にhard reset
1. 退避ブランチのコミットを[cherry pick](#cherry-pick)
1. 退避ブランチを削除

という手順で作業することを繰り返し、仕組みが理解できた段階でrebaseを使用するよう切り替える、という流れを推奨する。

### cat-file
[Gitオブジェクト](#gitオブジェクト)の内容を表示するコマンド。
`git cat-file -p <オブジェクトのハッシュ>`のように`-p`オプションを付与することで、オブジェクトの種類に応じわかりやすい形で表示してくれる。

## GitHub
当記事内では、GitHub社が提供するWebサービスを指す。
バージョン管理システムである[Git](#git)及び、それを制御する[gitコマンド](#git-1)とは別物であることに注意。
主に、GitHubが提供する以下の機能を利用して開発を行う。

### Issue
本来はバグ票のようなものであるが、当記事が想定している開発スタイルではバグ管理に留まらずタスク管理ツールとして用いる。(RedmineやTracのような[バグトラッキングシステム](https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%B0%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)と同様)
「Issueの起票」をコーディング含め**全ての作業の起点**とすることで、トレーサビリティを担保する。
他の開発者への質問や相談もIssueとして起票することを推奨する。

### Pull Request
自身の[ブランチ](#ブランチ)の作業内容を、指定した[リモートリブランチ](#リモートブランチ)に取り込むよう依頼する機能。
reviewerはここにレビューコメントを記入し、revieweeとやり取りする。
略して「PR」と書くことも多い。

当記事が(略)では、[featureブランチ](#featureブランチ)での作業内容を同一リポジトリ内の[mainブランチ](#デフォルトブランチ)に取り込むためにレビューを依頼する目的で利用することが基本となるため、GitLabのように「Merge Request」という名称のほうがしっくりくるかも知れない。

### Organization
組織として複数の[リポジトリ](#リポジトリ)を纏めて管理する機能。

### Milestone
[Issue](#issue)の付属機能。文字通りマイルストーンを作成し、各Issueや[PR](#pull-request)をマイルストーンに紐付けることができる。
各タスクの期限管理に利用すると良い。

### Project
[Organization](#organization)内の[リポジトリ](#リポジトリ)を跨いで[Issue](#issue)や[PR](#pull-request)を纏め、タスク管理ツールとして利用できる。
Trelloのようなカンバン形式で表示したり、マイルストーン単位でグルーピングした表形式で表示したりと、見た目の自由度はそれなりにある。
[GitHub](#github)ではIssueとPRはほぼ同列に扱われるためそれら全てをProjectに紐付けることも可能だが、管理が煩雑になるので筆者はIssueのみを紐付けるようにしている。
各Issueに対し進捗状況やpriorityを設定する手間が増えるため、得られるメリットと天秤に掛けた上で利用するか否かを適宜判断すること。

## 更新履歴
- 2022/10/17
    - [HEAD](#head)の項を加筆修正
    - 昔ながらの癖で「master」と書いてしまっていた箇所を「main」 に修正
- 2022/10/13
    - 書きかけの部分もあるがひとまず投稿