Git・GitHub (Flutter Roadmap Version Control Systems / Repo Hosting Services)

## はじめに
Flutterを網羅的に学習するにあたって[Roadmap](https://roadmap.sh/flutter)を使って学習を進めることにしました。

この記事では、Flutter初学者やこれからFlutterを学習し始める方に向けて、**Git・GitHub**についてまとめています。

RoadmapはFlutterだけでなく、他の言語やスキルのロードマップも提供されており、何から学習して良いか分からないと悩んでいる方にとって有用なサイトになっています。
ぜひ[Roadmap](https://roadmap.sh/)を利用して学習してみてください。

## Roadmapとは

簡潔に言えば、Roadmap.shは学習者にとっての**ガイドブック**であり、**学習の方向性を提供する学習ロードマップサイト**です。

初心者から上級者まで、ステップバイステップでスキルを習得するための情報が提供されています。

学習の進め方が分かりやすく示されているだけでなく、個々の項目に参考資料やリソースへのリンクも提供されているので、学習者は目標を設定し、自分自身のペースで学習を進めることができます。

## Git・GitHub
FlutterロードマップVersion Control Systems / Repo Hosting Servicesでは以下の12のサイトが紹介されています。興味のある方はぜひお読みください。

- Version Control System Introduction: https://www.youtube.com/watch?v=zbKdDsNNOhg
- Git & GitHub Crash Course For Beginners: https://www.youtube.com/watch?v=SWYqp7iY_Tc
- Learn Git in 20 Minutes: https://www.youtube.com/watch?v=Y9XZQO1n_7c&t=21s
- Git & GitHub Crash Course For Beginners: https://www.youtube.com/watch?v=SWYqp7iY_Tc
- Learn Git with Tutorials, News and Tips - Atlassian: https://www.atlassian.com/git
- Git Cheat Sheet: https://cs.fyi/guide/git-cheatsheet
- Host Flutter Website On GitHub Pages: https://www.youtube.com/watch?v=z-yOqoQ2q6s
- How to Deploy a Flutter Web App?: https://medium.com/solute-labs/flutter-for-web-how-to-deploy-a-flutter-web-app-c7d9db7ced2e
- Deploying - Flutter: https://docs.flutter.dev/deployment/web#deploying-to-the-web
- Git and GitHub for Beginners - Crash Course: https://www.youtube.com/watch?v=RGOj5yH7evk
- Get Started with Github: https://docs.github.com/en
- GitHub Tutorial – for Beginners: https://www.freecodecamp.org/news/git-and-github-for-beginners/


## バージョン管理システム (Version Control Systems)とは
**バージョン管理システム** (Version Control Systems)とは、ソフトウェア開発やコンテンツ管理などで使用されるツールで、ファイルやプロジェクトの**変更履歴を記録し、管理する**ために使用されます。

代表的なVCS(Version Control Systems)には**Git**、**Subversion**（SVN）、**Mercurial**、**CVS**などがあり、その中でも**Git**は特に広く使用されており、オープソース[^1]のプロジェクトや企業でのソフトウェア開発において主流になっています。

### **VCSの特徴**
#### 1. 変更の記録とトラッキング
プロジェクト内の全てのファイルとディレクトリの変更を記録します。新しいファイルの追加、既存ファイルの変更、ファイルの削除など、どのような変更が行われたかが、明確になり、誰が変更を行なったかも追跡できます。

#### 2. バージョン管理
プロジェクトの異なるバージョンを作成して、管理することができます。これによって、過去の状態に戻ったり、特定のバージョンを比較したりすることが可能です。バージョン間の差分を確認することで、バグの追跡が容易になります。

#### 3. 共同開発
複数の開発者が同じプロジェクトで協力しながら開発することができます。各開発者は自分の変更をコミットして、変更が他の開発者と競合しないように、マージを行います。

#### 4. バックアップと復元
ファイルの変更履歴を保持するため、データのバックアップと復元が可能です。誤ってデータを削除した場合や問題が発生した場合でも、以前の状態に戻すことができます。

#### 5. ブランチとマージ
異なるバージョンを独立して開発できるブランチ(分岐)を作成できるので、これらのブランチをマージ(統合)することにより、新しいバージョンを作成することができます。これにより、新機能の開発やバグ修正を安全に行うことが可能です。

#### 6. リモートリポジトリ
多くのVCS(Version Control Systems)はリモートリポジトリをサポートしており、複数の開発者やチームが分散して作業することができます。

## Gitとは
**Gitは分散型バージョン管理システム**(DVCS)の一つで、ソフトウェア開発やプロジェクト管理で広く使用されています。

### Gitの特徴

#### 1. 分散型
Gitは**分散型のバージョン管理システム**です。これは、**リモートリポジトリ**と**ローカルリポジトリ**の両方にコードの**完全なコピー**が存在し、各開発者が独立して作業ができることを意味しています。これによって、オフラインで作業したり、異なるブランチで作業したりすることが可能になります。

**バージョン管理管理システム**には**中央集中型**と**分散型**が存在します。以下リンクでそれぞれの違いについて説明されているので、興味のある方は是非読んでみてください。

https://qiita.com/y518gaku/items/9a789b4bddfabe687dfa

https://next.rikunabi.com/journal/20160908_t12_iq/

#### 2. バージョン管理
プロジェクトの**変更履歴を追跡**し、バージョン管理を行います。各変更は**コミット**（commit）として記録され、プロジェクトの異なるバージョン間の差分を確認できます。これにより、バグのトラッキングや特定のバージョンの復元が可能になります。

#### 3. ブランチ
Gitは**ブランチ**と呼ばれる**独立した開発空間**を作成することができます。新機能の開発やバグ修正を行う際に、ブランチを作成して作業し、後で**マージ**することによって、メインのコードに統合できます。これにより、コードの変更と並行開発が安全に行えるのです。

以下リンクで**ブランチ**について説明されているので、興味のある方は是非読んでみてください。

https://backlog.com/ja/git-tutorial/stepup/01/

#### 4. リモートリポジトリ
Gitは**リモートリポジトリ**をサポートしており、複数の開発者がコードを共有できるようにしています。主要なリモートリポジトリサービスとして**GitHub**、**GitLab**、**Bitbucket**などがあります。

**リモートリポジトリ**についてわかりやすい記事があったので、是非読んでみてください。

https://wa3.i-3-i.info/word18803.html

#### 5. コミット
**コミットは変更セットを記録する単位**です。コミットにはメッセージ(**コミットメッセージ**)を含むことができるため、他の開発者に**変更の目的を説明する**ことができます。

**コミット**についてわかりやすい記事があったので、是非読んでみてください。

https://backlog.com/ja/git-tutorial/intro/03/

#### 6. マージ
**マージは異なるブランチを統合する**ためのプロセスです。Gitはマージする際に変更箇所が異なっていて、競合が起きた場合、**マージコンフリクト**（競合）を自動的に検出することができます。そのため、開発者が競合を解決することが可能になるのです。

**マージ**についてわかりやすい記事があったので、是非読んでみてください。

https://www.sejuku.net/blog/71003

#### 7. タグ
**タグは特定のコミットに名前を付ける**ことができ、リリースバージョンなど重要なポイントを示すのに使用されます。

**タグ**についてわかりやすい記事があったので、是非読んでみてください。

https://www.sejuku.net/blog/72186#:~:text=%E3%80%8Cgit%20tag%E3%80%8D%E3%82%92%E4%B8%80%E8%A8%80,%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82

https://backlog.com/ja/git-tutorial/stepup/17/

https://qiita.com/k-penguin-sato/items/c62b47dd79f144c68dad

#### 8. ステージング
Gitには**ステージングエリア**があり、変更を**ステージングエリアに追加してからコミット**できます。これにより、**コミット前に変更内容を確認する**ことができるのです。

**ステージング**についてわかりやすい記事があったので、是非読んでみてください。

https://www.ninton.co.jp/archives/3218

https://kray.jp/blog/expound-git-add/

https://qiita.com/takuyanin/items/8d5226fd5834e6ebc564

https://saponote.hatenablog.com/entry/2022/07/01/000000

## Gitの使用方法
Gitの機能やコマンドはさまざまで、オプションを使用するとかなり高度な操作まで行えるようになります。ここでは、開発を行う上で使用する一般的なコマンドについて説明していきます。

### 1. Git init
`git init`コマンドは、一言で言うと**リポジトリ[^2]を新規に作成**するときに使用するコマンドです。

`init`コマンドを実行すると、現在のディレクトリまたは指定したディレクトリに`.git`というリポジトリを構成するディレクトリが作成されます。

Gitでバージョン管理を始めるには、**リポジトリの初期化**をしなければなりません。`.git`ディレクトリにはGitで使用するファイルが新規に作成されるため、既に存在するリポジトリを**再度初期化したい場合**にも使用できます。

https://www.sejuku.net/blog/71268

### 2. Git clone
`git clone`は特定のリポジトリの内容(ファイルやディレクトリ)を別のリポジトリに複製（**クローン**）するためのコマンドです。

一般的には**リモートリポジトリ**を**ローカルリポジトリ**に**クローン**する際に使用されるため、既存のプロジェクトを開始する時に使うコマンドになります。

```bash
git clone https://github.com/username/repo.git
```

https://www.sejuku.net/blog/71436

https://tech-blog.rakus.co.jp/entry/20220624/git

### 3. Git add / Git commit
`git add`コマンドを使うと、**ステージングエリア**にファイルを追加することができます。gitではステージングエリアに、新規のファイルや編集したファイルを一度乗せた後、コミットするため、コミットの対象となるのはステージされたコンテンツだけになります。

```bash
git add ファイル名 // 指定したファイル・ディレクトリのみ
git add . //　すべてのファイル・ディレクトリ
git add *.css //　すべてのCSSファイル
git add -n //　追加されるファイルを調べる
git add -u //　変更されたファイルを追加する
git rm --cached //　addしてしまったファイルを除外
```

https://codelikes.com/git-add/

https://eng-entrance.com/git-add

https://qiita.com/konweb/items/621722f67fdd8f86a017

`git commit`コマンドとは一言で言うと**追加・変更したファイルをGitに登録する**ためのコマンドです。通常のファイル操作では変更した内容を上書き保存すれば、ファイルの内容が変更されますが、Gitのリポジトリに変更内容を登録（保存）するためには、`git commit`を使用する必要があります。

```bash
git add ファイル名 // 指定したファイル・ディレクトリのみ
git commit -a //変更のあったファイルすべて
git commit --amend //直前のコミットを取り消す
git commit -v //変更点を表示してコミット
```

https://www.sejuku.net/blog/71279

### 4. Git diff / Git status
`git diff`コマンドとは2つのファイルを比較して違いなどを探すことができるコマンドです。

`git diff`コマンドで表示するのは作業ディレクトリとステージングエリア間の変更差分です。ステージングエリアとローカルリポジトリ間の変更差分を表示す流には`--staged`オプションを付与します。

```bash
git diff // カレントディレクトリの差分を表示
git diff ファイル名 // 指定したファイル・ディレクトリのみ
git diff --staged // ステージングエリアとローカルリポジトリ間の変更差分
git diff HEAD^ // 最後のコミットからの差分を表示
git diff --name-only HEAD^ // 差分ファイルを表示
git diff file1.txt file2.txt // 特定ファイルの差分
git diff commit1 commit2 // コミットの差分
```

https://phoeducation.work/entry/20210804/1628031480

`git status`コマンドは、**作業ディレクトリ**の状態と**ステージングエリア**の状態を表示するコマンドです。このコマンドを実行すると、**どの変更がステージング済み**で**どの変更がまだステージングされていない**のか、**どのファイルが Git の追跡対象外になっているのか**が表示されます。

```bash
git status
```

https://www.atlassian.com/ja/git/tutorials/inspecting-a-repository

https://www.sejuku.net/blog/71857

### 5. Git log
`git log`コマンドを使うことで、コミットした履歴を確認することができます。使用例としては作業中のファイルを**特定のバージョンに戻したい**場合などが挙げられます。特定のバージョンに戻すためには`git rebase`コマンドを用いますが、その際に`git log`で得られるコミット番号が役に立ちます。

```bash
git log // コミットのログが見れる
git reflog // Git内のコマンド操作の全ての履歴を見れる
git reflog origin/branch_name //pushのログが見れる
```

https://codelikes.com/git-log/

https://prograshi.com/general/git/reflog-head-at-and-git-reset/

### 6. Git branch / Git checkout
ブランチを作成すると、現在の開発フローから離れて、別のコミット履歴を記録していくことが可能になります。**ブランチ作成**には2通りあり、`git branch ブランチ名`もしくは`git checkout -b ブランチ名`で作成します。

```bash
git branch ブランチ名
```
`branch`コマンドを利用した作成方法はシンプルです。`git branch`の後に**作成したいブランチ名**を記述するのみです。

```bash
git checkout -b ブランチ名
```
`checkout`コマンドを利用した作成方法は`-b`オプションを使用します。`-b`オプションをつけないとただのブランチの切り替えになってしまうので、ブランチを作成する際には必ず`-b`オプションを付与してください。

**ローカルのブランチ一覧**を確認したい場合は、`git branch`コマンドを実行します。
先頭に`*`がついているものが現在のブランチです。

```bash
git branch
  issue1
* master
```

**現在いるブランチから切り替えたい**場合は、`git checkout`コマンドを実行します。

```bash
git checkout 切り替えたいブランチ名
```

```bash: ブランチの切り替え例
git branch
  issue1
* master

git checkout issue1

git branch
* issue1
  master
```

```
git branch -d [branch_name]  // ブランチの削除
git branch -m [branch_name]  // 現在のブランチ名の変更
git branch -a // リモートとローカルのブランチの一覧
git branch -r // リモートブランチの一覧
```

https://www.sejuku.net/blog/71612

### 7. Git fetch / Git pull
`git pull`コマンドを使用すると、gitリポジトリにある最新のソースコードをローカルリポジトリに反映することができます。引数なしで`git pull`コマンドを実行した場合は、現在作業中のブランチと関連付けられているリモートリポジトリのブランチを対象に`pull`が行われます。

関連づけられているブランチのことを**アップストリームブランチ**といいます。アップストリームブランチを確認するには`git branch`に`-vv`オプションを付与します。

```bash
git pull // 関連付けられているブランチから取得する

git branch -vv // アップストリームブランチを確認する

git pull <remote> <branch> // デフォルト
git pull origin main // 実行例: リモートリポジトリのmainブランチの最新コードを取得
```

https://tech-blog.rakus.co.jp/entry/20220805/git

`git fetch`コマンドを実行すると、リモートリポジトリの最新の履歴の取得だけを行うことができます。取得したコミットは、名前の無いブランチとして取り込まれます。このブランチはFETCH_HEADという名前でチェックアウトすることができます。

`git fetch`コマンドはローカルの**masterブランチ**まで更新されていない（mergeされていない）ので、`git reset --hard HEAD`を使用することで、直前のcommitまで戻すことができます。

```bash
git fetch

git reset --hard HEAD // 直前のcommitまで戻して、無かった事にします。
```

リモートから情報をローカルに持ってきますが、場所は**masterブランチ**ではなく、**origin/masterブランチ**に取り込まれます。

- **masterブランチ:** ローカルの中心となる統合ブランチで、他のローカルの作業ブランチと繋がったもの。
- **origin/masterブランチ:** ローカルにある、リモートのmasterブランチを追跡するリモート追跡ブランチ。

`git pull`は、`git fetch`、`git merge`を同時に行うコマンドです。そのため、`git pull`はリモートの**masterブランチ**から、ローカルの**origin/master**ブランチを介して、ローカルの**master**まで一気に最新情報を持ってきます。

`git pull = git fetch + git merge`

https://backlog.com/ja/git-tutorial/stepup/15/

https://qiita.com/wann/items/688bc17460a457104d7d

### 8. Git push
`git push`コマンドを使うことで、Gitの**リモートリポジトリ**に現在のコミット履歴を反映させることができます。

**コミットまではローカル**で管理していますが、**リモートリポジトリ**にプッシュすると**Publicの場合は全体公開**され、**Privateの場合は招待しているチームのユーザー**に公開されます。

```
git push <remote> <remote branch> // デフォルト

git branch
  issue1
* master

// 実行例: ローカルのmasterブランチからリモートのmasterブランチへ最終コミットを反映
git push origin master 
```

https://codelikes.com/git-commit-push/

## リポジトリホスティングサービス(Repository Hosting Services)とは
**リポジトリホスティングサービス**（Repository Hosting Service）は、ソースコード管理やバージョン管理システム（GitやSubversionなど）を使用する開発者やチーム向けに提供される**クラウドベースのプラットフォーム**です。

これらのサービスは、コード、ドキュメントなどを安全に管理し、共有するためのツールとして提供されます。

一般的なリポジトリホスティングサービスには**GitHub**、**GitLab**、**Bitbucket**、**AWS CodeCommit**、**Microsoft Azure DevOps**などがあります。

### リポジトリホスティングサービスの特徴

#### 1. ソースコードホスティング
開発者は自分のプロジェクトのソースコードをリポジトリにアップロードし、バージョン管理を行うことができます。これにより、**コードの変更履歴**、**ブランチ**、**タグ**などが追跡可能なります。

#### 2. コラボレーション
**複数の開発者が同じプロジェクトにアクセス**し、コードの共同編集やレビューができます。多くのリポジトリホスティングサービスは、チームでの協力を強化するためのツールを提供しています。

#### 3. バグトラッキング
プロジェクトに関連する**バグや課題**を管理するための機能を提供しています。

#### 4. CI/CD統合
リポジトリホスティングサービスは一般的に**CI/CD**[^3][^4]（継続的インテグレーション/継続的デリバリー）ツールと統合されており、**自動ビルド**、**テスト**、**デプロイ**を行うためのパイプラインを設定することができます。

#### 5. セキュリティ
**アクセス制御**、**認証**、**監査ログ**などさまざまなセキュリティ機能が提供されており、**プライベートリポジトリ**の作成も行えるため、プロジェクトを安全に管理することができます。

#### 6. 統計と分析
**プロジェクトの進捗状況**や**コードの品質に関するデータを収集・分析する**ツールが提供されています。**リポジトリの閲覧**、**コードの比較**、**変更の追跡**なども行えます。

## GitHubとは
ソフトウェア開発者やチームがソースコードを**管理、共有する**ための**ウェブホスティングサービス**です。

GitHubでソースコードを管理すれば、**最新版や変更履歴**が分かりやすくなります。また**共同での開発**に役立つ機能も豊富なため、プロジェクトに携わるプログラマーが多くなっても、スムーズに開発を進められます。

また、**無料で**非公開のリポジトリ（**プライベートリポジトリ**）を作成するなど開発に必要な機能を無料で利用することができます。

https://www.kagoya.jp/howto/it-glossary/develop/github/

### GitHubの特徴

#### 1. フォーク
GitHubには、**フォーク**という機能があります。一つのプロジェクトが複数に分派していくのを食器のフォークの先端に例えているのが名称の所以です。誰かのリポジトリをコピーする際に使用されます。オリジナルのものに対する**編集・アクセス権限がなく**ても、**自分の環境で改変が可能**です。

#### 2. プルリクエスト
自分が行った**変更をオリジナルのものに反映したい**時に使われます。オリジナルのオーナーに**プルリクエスト**と呼ばれる通知を送ることができるのです。

#### 3. マージ
**プルリクエスト**を受け取ったオーナーは、**ボタンをクリックするだけ**でリポジトリに対して行われた変更を自分のリポジトリにも取り入れられます。人のコードを自分のコードに導入するのを**マージする**と言います。**マージ**は、複数の開発者が関わるプロジェクトにおいて最重要工程であり、GitHubではそれを**安全かつ迅速**に行うことができるのです。

https://www.sejuku.net/blog/7901

## GitHubのセットアップ

### 1. GitHubのアカウント作成
[GitHub](https://github.com/)へアクセスし、**ユーザ名・メールアドレス・パスワード**を入力し、「**Sign up for GitHub**」ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368449/cae18102-2267-1433-c1e4-fc60fbb82c25.png)


次に「**Verify your account**」の設問に回答後、「**Join a free plan**」を選択します。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368449/4a94b6db-032b-de06-08fb-7873958f85fe.png)

「**Welcome to GitHub**」と表示された画面へ進みますが、一番下に進み、「**Complete setup**」ボタンをクリックしてください。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368449/5d94a233-5eb7-9c53-e52c-cb8d71300381.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368449/78b0c4a4-1e6a-0669-b3a3-4afca3c69863.png)

最後に以下画面が表示され、入力したメールアドレスに認証用メールが配信されますので、認証を行ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368449/a736a303-a16a-6168-2eba-af317637944a.png)

### 2. リモートリポジトリを作成する

GitHubにアクセスし、リモートリポジトリを作成します。
トップ画面で「**Create Repository**」ボタンをクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368449/2c74fc4e-6c6b-e2e7-df9d-640e0ce4b309.png)


リポジトリ作成画面に移動するので、「**Repository name**」には任意のリポジトリ名を入力します。

次にリポジトリの種類として、「**Public**」か「**Private**」を選択します。
**Publicの場合は全体公開**され、**Privateの場合は招待しているチームのユーザーのみ**に公開されます。

次に「**Initialize this repository with a README**」ですが、**リポジトリの説明や使い方を記述するREADME[^5]ファイル**を事前作成しておく場合にはチェックをONにします。

最後に「**Create repository**」ボタンをクリックすると、リポジトリが作成されます。

リポジトリを作成した後の流れなど**より詳細でわかりやすい記事**があったので、以下リンクから是非読んでみてください。

https://tech-blog.rakus.co.jp/entry/20200529/git

[^1]: **オープンソース**
ソフトウェアを構成しているプログラム「ソースコード」を、無償で一般公開することです。 一般公開することによって、誰でもそのソフトウェアの改良や再配布が行なえるようになります。 
[こちら](https://wa3.i-3-i.info/word1163.html)にわかりやすい記事があったので、是非読んでみてください。

[^2]: **リポジトリ**
簡潔に言うとファイルやプログラムなどさまざまな情報・データを保管する場所のことです。
[こちら](https://wa3.i-3-i.info/word15664.html)にわかりやすい記事があったので、是非読んでみてください。

[^3]: **CI(Continuous Integration) 継続的インテグレーション**
特定の技術を指すものではなく、ソフトウェアの**変更をテスト**して、**自動で**本番環境に適用できるような状態にしておく開発手法のことです。ソースコードの変更を、定期的にビルドおよびテストして、共通のリポジトリに統合します。CIを用いることによって、クラスや各種のモジュールなど構成するすべての要素に対して実施するテストを自動化できます。そのため、プログラムの不具合を早く見つけ、すぐに修復できるのです。
[こちら](https://www.sbbit.jp/article/cont1/81640)にわかりやすい記事があったので、是非読んでみてください。


[^4]: **CD(Continuous Delivery) 継続的デリバリー**
CDとは検証済みコードの**リリースを自動化**することを指します。コード変更のマージから本番環境に対応するためのビルドまで、すべての段階で**テストとコードリリースを自動化**できます。これにより、本番環境にアプリケーションをすぐデプロイできるのです。
[こちら](https://it-trend.jp/cicd_tool/article/937-874)にわかりやすい記事があったので、是非読んでみてください。

[^5]: **README**
簡潔に言えば、ソフトやプログラムの部品などの説明書ファイルのことです。
[こちら](https://wa3.i-3-i.info/word15053.html)にわかりやすい記事があったので、是非読んでみてください。