Git・GitHubの基礎その１

# はじめに
勉強を兼ねて個人的に開発を行っており、Git・GitHubを使ってソースコード管理を行っています。実際に使ってみると、覚えることが多く、難しいです。
なので、自分のためにも一度アウトプットをしようと思います。

# 目次
1. [Gitのざっくりとした説明](#Gitのざっくりとした説明)
1-1. [まずは全体図から](#まずは全体図から)
1-2. [ざっくりな用語説明](#ざっくりな用語説明)
2. [用語の詳しい説明](#用語の詳しい説明)
2-1. [リポジトリ](#リポジトリ)
2-2. [ローカルリポジトリ](#ローカルリポジトリ)
2-3. [リモートリポジトリ](#リモートリポジトリ)
2-4. [ステージングエリア](#)
2-5. [ステージング](#ステージングgit-add)
2-6. [コミット](#コミットgit-commit)
2-7. [プッシュ](#プッシュgit-push)
2-8. [プッシュとコミットの違い](#プッシュとコミットの違い)
2-9. [フェッチ](#フェッチgit-fetch)
2-10. [プル](#プルgit-pull)
2-11. [クローン](#クローンgit-clone)
2-12. [フェッチとプルとクローンの違い](#フェッチとプルとクローンの違い)
# Gitのざっくりとした説明
イメージをつかむために簡潔な説明からします。
## まずは全体図から
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3373520/4b9f2f3e-a5df-e867-8258-1738f8fbdcdb.png)

## ざっくりな用語説明
- **リポジトリ**
ソースコードを保存するデータベースみたいなもの。
- **ローカルリポジトリ**
PCの中にあるリポジトリ。
- **リモートリポジトリ**
クラウド上に存在するリポジトリ。GitHubなどを指定する。
- **ステージングエリア**
ローカルリポジトリに変更を反映させたいファイルを置くエリア。
- **ステージング**
ステージングエリアへファイルを送ること。
- **コミット**
ステージングエリアに置かれたファイルの変更をローカルリポジトリに反映させること。
- **プッシュ**
ローカルリポジトリの内容をリモートリポジトリに反映させること。
- **フェッチ・プル・クローン**
リモートリポジトリの内容をローカルリポジトリへ反映させること。

# 用語の詳しい説明
chatGPTで作成し編集しました。

## リポジトリ
ソフトウェア開発やバージョン管理システムにおいて、ファイルやプロジェクトの変更履歴を管理するデータベースのことです。一般的には、特定のプロジェクトやソフトウェアのコード、ドキュメント、画像などのファイルが含まれます。

具体的には、ソフトウェア開発において、リポジトリはプログラムのソースコードやその他のファイルを保存する場所として機能します。開発者はファイルの変更や追加をリポジトリにコミットし、変更の履歴を管理します。これにより、チームメンバーは他の開発者が行った変更を追跡し、必要に応じてコードのマージや競合の解消を行うことができます。

## ローカルリポジトリ
   - ローカルリポジトリは、開発者のコンピュータ上に存在するリポジトリです。
   - 開発者がプログラムのソースコードやその他のファイルを変更し、コミットする場所です。
   - ローカルリポジトリは、バージョン管理システム（例: Git、Subversion）によって管理されます。
   - 開発者はローカルリポジトリ内での作業を行い、変更をコミットすることで履歴を記録します。

## リモートリポジトリ
   - リモートリポジトリは、オンライン上のサーバーに配置されたリポジトリです。
   - チーム全体がアクセスして共同で作業する場所です。
   - リモートリポジトリは、開発者がローカルリポジトリから変更をプッシュし、他の開発者が変更をプルすることで同期されます。
   - よく使われるリモートリポジトリのプラットフォームには、GitHub、GitLab、Bitbucketなどがあります。
   - リモートリポジトリは、バックアップや共有、チームコラボレーションのために使用されます。

開発者は通常、ローカルリポジトリで作業を行い、変更をリモートリポジトリにプッシュして他の開発者と共有します。これにより、複数の開発者が同じプロジェクトで同時に作業し、変更をトラッキングして管理することができます。


## ステージングエリア
Gitの**ステージングエリア**（または**インデックス**とも呼ばれます）は、Gitのワークフローの一部であり、ファイルの変更内容を一時的に保存し、次にコミットする準備を整えるための領域です。

具体的には、ファイルを修正した後、その変更をステージングエリアに追加します。ステージングエリアに追加された変更は、次のコミットに含まれます。これにより、複数の変更をまとめてコミットする前に、変更の内容を検討し、必要な場合には変更をまとめることができます。

ステージングエリアを使用することで、コミットされる変更を柔軟に制御できます。たとえば、ファイルの一部の変更のみをコミットすることや、不要な変更を除外することができます。

## ステージング（git add）
ファイルをGitのステージングエリアに追加する方法はいくつかあります。以下に、一般的な方法を示します。

1. **個々のファイルをステージングする（git add）**
特定のファイルをステージングするには、次のコマンドを使用します。
   ```bash:bash
   git add <ファイル名>
   ```
   このコマンドは、指定したファイルをステージングエリアに追加します。

2. **変更されたすべてのファイルをステージングする**
ワーキングディレクトリ内の変更されたすべてのファイルをステージングするには、次のコマンドを使用します
    ```bash:bash
   git add .
   ```
   このコマンドは、現在のディレクトリとそのサブディレクトリ内のすべての変更されたファイルをステージングエリアに追加します。

3. **変更の一部をステージングする**
一部の変更だけをステージングするには、まず`git add -p`コマンドを使用して対話的なパッチモードを開始します。その後、変更をステージングしたい場合には`y`を、ステージングしない場合には`n`を入力します。

これらのコマンドを使用することで、ファイルや変更のステージングを効率的に行うことができます。

## コミット（git commit）
ソースコードやファイルの変更をローカルリポジトリに記録する操作です。ステージングエリアにある変更がコミットされます。コミットを行うことで、変更の履歴や変更内容がリポジトリ内に保存されます。コミットはGitのバージョン管理システムにおいて非常に重要な操作であり、以下のような特徴があります。

1. **変更の記録**
コミットは、ファイルの追加、変更、削除などの変更を記録します。開発者は、コミットメッセージを付けて変更内容を説明することが一般的です。
2. **一意の識別子**
各コミットは一意の識別子（ハッシュ値）を持ちます。この識別子は、コミットの内容や履歴を一意に特定するために使用されます。

3. **履歴の分岐とマージ**: コミットを繰り返すことで、リポジトリ内の変更履歴が記録されます。また、異なるブランチでの作業を統合するためにマージ操作が行われる際にも、コミットが使用されます。

4. **時間の経過による追跡**: コミットは時間の経過によって並べられ、特定の時点でのプロジェクトの状態を追跡することができます。これにより、過去の状態に簡単に戻ることができます。

5. **変更の管理**: コミットを使用することで、複数の開発者が同じプロジェクトで作業する際に、変更の管理とトラッキングが容易になります。誰が、いつ、どのような変更を行ったかを明確に把握することができます。

`git commit`コマンドで、コミットする。ここでは、基本的な`git commit`コマンドの使い方を説明します。
ステージングエリアに変更を追加した後、コミットを作成します。コミットを作成するには、`git commit`コマンドを使用します。例えば、次のようにしてコミットを作成します。
   ```bash:bash
   git commit -m "コミットメッセージ"
   ```

   `-m`オプションは、コミットメッセージを直接コマンドラインで指定するためのオプションです。コミットメッセージには、変更内容や目的などを説明する簡潔な説明を含めることが一般的です。

これで、変更内容がコミットされました。コミットがローカルリポジトリに保存され、一意の識別子（ハッシュ値）が付与されます。必要に応じて、他のGit操作と組み合わせて、変更を管理することができます。

また、`git commit`コマンドの他にもさまざまなオプションがあります。詳細については、`git commit --help`コマンドを使用してヘルプを参照するか、Gitのドキュメントを確認してください。
コミットはGitの中心的な概念であり、プロジェクトの履歴と変更を管理する上で欠かせない操作です。

## プッシュ（git push）
Gitにおいてローカルリポジトリで行われたコミットをリモートリポジトリに送信する操作を指します。具体的には、ローカルリポジトリに行われた変更をリモートリポジトリにアップロードすることで、他の開発者と変更を共有したり、リモートリポジトリとの同期を取ったりすることができます。

プッシュ操作を行うことで、ローカルリポジトリで行われたコミットがリモートリポジトリに反映され、他の開発者がその変更を取得できるようになります。また、複数の開発者が同じプロジェクトで作業する際に、プッシュを使用して変更を共有し、チーム全体の進捗を同期させることができます。
`git push`コマンドで、ローカルリポジトリに存在するコミットをリモートリポジトリに送信します。具体的には、ローカルリポジトリにコミットされた変更をリモートリポジトリにアップロードし、他の開発者と変更を共有するための操作です。

ここでは、`git push`コマンドの基本的な使い方を説明します。

1. **リモートブランチに変更をプッシュする**:
   ```bash:bash
   git push <リモート名> <ローカルブランチ名>:<リモートブランチ名>
   ```
   - `<リモート名>`: リモートリポジトリの名前。通常は"origin"と呼ばれます。
   - `<ローカルブランチ名>`: プッシュするローカルブランチの名前。
   - `<リモートブランチ名>`: プッシュ先のリモートブランチの名前。

   例えば、ローカルの`main`ブランチを`origin`リモートリポジトリの`main`ブランチにプッシュする場合は次のようになります。
   ```bash:bash
   git push origin main
   ```

2. **現在のブランチの変更をプッシュする**:
   ```bash:bash
   git push <リモート名> <現在のブランチ名>
   ```
   現在のブランチを`<リモート名>`の同名のブランチにプッシュします。

   例えば、現在のブランチを`origin`リモートリポジトリの同名のブランチにプッシュする場合は次のようになります。
   ```bash:bash
   git push origin HEAD
   ```

3. **すべてのトラッキングブランチの変更をプッシュする**:
   ```bash:bash
   git push <リモート名> --all
   ```
   リモートにトラッキングされているすべてのローカルブランチの変更をプッシュします。

これらは`git push`コマンドの基本的な使い方です。リモートリポジトリへの変更の共有や同期にはよく使用されます。必要に応じて、さまざまなオプションを使用して詳細な操作を行うこともできます。

## プッシュとコミットの違い
プッシュ（Push）とコミット（Commit）は、Gitで異なる操作ですが、密接に関連しています。

1. **コミット（Commit）**:
   - コミットは、ソースコードやファイルの変更をリポジトリに記録する操作です。
   - ローカルリポジトリで行われます。
   - 変更内容をステージングエリアに追加し、その変更をリポジトリにコミットします。
   - コミットはリポジトリ内の履歴として保存され、一意の識別子（ハッシュ値）を持ちます。
   - コミットメッセージを使用して、変更内容や目的を説明することが一般的です。

2. **プッシュ（Push）**:
   - プッシュは、ローカルリポジトリ内で行われたコミットをリモートリポジトリに送信する操作です。
   - ローカルリポジトリからリモートリポジトリに変更をアップロードします。
   - チームメンバーと変更を共有したり、リモートリポジトリとの同期を取ったりするために使用されます。
   - 他の開発者が変更をプル（Pull）して取得できるようにします。

要するに、コミットはローカルリポジトリ内で行われた変更を記録し、プッシュはそのコミットをリモートリポジトリに送信して他の開発者と共有する操作です。コミットがローカルで行われた変更の確定であり、プッシュがその変更を共有するための手段と言えます。

## フェッチ（git fetch）
`git fetch`は、リモートリポジトリから最新の変更を取得し、ローカルのリポジトリに反映するGitコマンドです。具体的には、リモートリポジトリに新しいコミットがあるかどうかを確認し、ローカルのリポジトリには存在しないがリモートリポジトリに存在するコミットをダウンロードします。ただし、ローカルのブランチには直接反映されず、リモートトラッキングブランチ（origin/mainなど）にのみ反映されます。

git fetchを使用すると、次のようなことができます。

- リモートリポジトリの最新の変更を取得し、ローカルのリポジトリに反映する
- リモートリポジトリの最新の情報を確認し、ローカルのリポジトリが古くなっていないことを保証する
- リモートトラッキングブランチを更新し、`git status`などのコマンドで現在の状態を確認できるようにする

git fetchは、リモートリポジトリの変更をローカルに取り込むだけで、現在の作業ブランチには変更が直接反映されません。変更を統合するには、`git merge`または`git rebase`を使用して、ローカルブランチに取り込む必要があります。

## プル（git pull）
`git pull`は、リモートリポジトリから最新の変更を取得し、ローカルのリポジトリに反映し、現在のブランチに自動的にマージまたはリベースするGitコマンドです。`git fetch`と`git merge`（または`git rebase`）の組み合わせとして機能します。

具体的には、`git pull`コマンドは次の手順を実行します。

`git fetch`を実行して、リモートリポジトリから最新の変更を取得し、ローカルのリポジトリに反映します。
リモートリポジトリの変更をローカルの作業ブランチにマージまたはリベースします。
つまり、`git pull`は、`git fetch`と`git merge`（または`git rebase`）を1つのコマンドで実行する便利な方法です。

使用法は次のとおりです。
```bash:bash
git pull [<リモート名>] [<ブランチ名>]
```
デフォルトでは、`git pull`は現在のブランチのリモートトラッキングブランチから変更を取得します。<リモート名>と<ブランチ名>を指定すると、他のリモートブランチから変更を取得できます。

## クローン（git clone）
`git clone`は、リモートリポジトリからローカルにコピーを作成するためのGitコマンドです。リポジトリの全ての履歴、ブランチ、タグ、およびコミットメッセージが含まれるローカルの複製を作成します。

具体的には、次のように使用します。

```bash:bash
git clone <リモートリポジトリのURL>
```
これにより、指定したリモートリポジトリのコピーがローカルのカレントディレクトリ内に作成されます。デフォルトでは、リモートリポジトリの名前と同じディレクトリが作成され、その中にコピーが配置されます。

`git clone`コマンドを使用すると、以下のことが実行されます。

リモートリポジトリから最新の履歴とファイルがダウンロードされます。
.gitディレクトリが作成され、ローカルリポジトリの情報が格納されます。
リモートリポジトリのHEADブランチが自動的にチェックアウトされます。
`git clone`コマンドは、新しいプロジェクトを開始する際や既存のプロジェクトに参加する際に使用されます。ローカルで作業を開始する前に、リモートリポジトリの最新の状態を取得して、自分の環境にコピーを作成します。

## フェッチとプルとクローンの違い
フェッチ（Fetch）、プル（Pull）、クローン（Clone）は、Gitでリモートリポジトリからローカルリポジトリに変更を取得するための異なる操作です。以下にそれぞれの違いを説明します。

1. **フェッチ（Fetch）**:
   - フェッチは、**リモートリポジトリから最新の変更を取得するだけで、実際にはローカルのブランチには変更が反映されません**。
   - フェッチは、リモートリポジトリの最新の履歴を取得し、ローカルリポジトリにその情報をダウンロードしますが、変更をマージしたり、ローカルのブランチに適用することはしません。
   - フェッチを使用すると、ローカルリポジトリのリモートトラッキングブランチが更新され、リモートリポジトリの変更が確認できます。

2. **プル（Pull）**:
   - プルは、**フェッチとマージを組み合わせた操作**です。リモートリポジトリから変更をフェッチし、ローカルのブランチにマージします。
   - プルは、フェッチしてからマージするため、リモートリポジトリの最新の変更をローカルに取り込むと同時に、ローカルのブランチに変更を適用します。
   - 単純なプル（`git pull`）は、リモートトラッキングブランチから変更をフェッチし、現在のブランチにマージします。

3. **クローン（Clone）**:
   - クローンは、**リモートリポジトリ全体をローカルに複製する操作**です。
   - クローンを使用すると、リモートリポジトリの全ての履歴やファイルがローカルにコピーされ、完全なローカルリポジトリが作成されます。
   - クローンは、プロジェクト全体を始める際に使用され、新しい作業ディレクトリを作成し、リポジトリの内容をすべてダウンロードします。

要するに、フェッチはリモートリポジトリの最新の変更を取得するだけで、プルはフェッチとマージを組み合わせてリモートの変更をローカルに適用し、クローンはリモートリポジトリ全体をローカルにコピーする操作です。