> For the complete documentation index, see [llms.txt](https://engineer.toggle.co.jp/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://engineer.toggle.co.jp/chapter-1-toggle-holdings-engineer-101/ji-chu-yan-xiu/git.md).

# Git

## **Gitの基本**

Gitは分散型バージョン管理システムであり、以下の基本原則に基づいています:

* リポジトリ（Repository）: ファイルやプロジェクトの変更履歴を管理する場所です。ローカルリポジトリとリモートリポジトリの2つのタイプがあります。
* コミット（Commit）: ファイルの変更をリポジトリに記録する単位です。コミットには一意の識別子があり、変更の内容やメッセージを含んでいます。
* ブランチ（Branch）: リポジトリ内のコミットの流れを分岐させるための仕組みです。ブランチを作成し、それぞれのブランチで独立した作業を行うことができます。
* プッシュ（Push）とプル（Pull）: ローカルリポジトリとリモートリポジトリの間で変更を同期するための操作です。プッシュはローカルの変更をリモートに反映し、プルはリモートの変更をローカルに取り込みます。

### **Gitのセットアップと初期設定**

Gitのセットアップと初期設定は、以下の手順に従って行います:

1. Gitのインストール: オフィシャルのGitウェブサイト（[https://git-scm.com/）からGitをダウンロードしてインストールします。インストーラに従って適切なオプションを選択してください。](https://git-scm.com/%EF%BC%89%E3%81%8B%E3%82%89Git%E3%82%92%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89%E3%81%97%E3%81%A6%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%BE%E3%81%99%E3%80%82%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%A9%E3%81%AB%E5%BE%93%E3%81%A3%E3%81%A6%E9%81%A9%E5%88%87%E3%81%AA%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%97%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82)
2. Gitの設定: Gitの設定を行います。以下のコマンドを実行して、ユーザ名とメールアドレスを設定します。

   ```bash
   git config --global user.name "Your Name"
   git config --global user.email "your.email@example.com"
   ```

   `--global`オプションを使用すると、設定がグローバルな範囲に適用されます。
3. 初期化とリポジトリの作成: プロジェクトディレクトリで`git init`コマンドを実行して、新しいGitリポジトリを作成します。

   ```bash
   cd /path/to/project
   git init
   ```

   これにより、プロジェクトディレクトリ内に`.git`ディレクトリが作成されます。

Gitのセットアップと初期設定が完了したら、バージョン管理を開始する準備が整いました。

## **ローカルリポジトリの操作**

ローカルリポジトリの操作について、リポジトリの初期化、ファイルの追跡とコミット、ブランチの作成と切り替え、コミットの修正と履歴の確認、コミットの取り消しと変更の取り込みについて説明します。

### **リポジトリの初期化**

新しいプロジェクトディレクトリをGitリポジトリとして初期化するために、以下のコマンドを使用します。

```bash
git init
```

このコマンドにより、プロジェクトディレクトリ内に`.git`ディレクトリが作成され、Gitリポジトリが初期化されます。

### **ファイルの追跡とコミット**

Gitでファイルを追跡し、変更をコミットするためには、以下の手順を実行します。

1. ファイルの追跡: 変更を追跡したいファイルを`git add`コマンドでステージングエリアに追加します。

   ```bash
   git add file.txt
   ```
2. コミットの作成: ステージングエリアに追加された変更をコミットし、リポジトリに記録します。

   ```bash
   git commit -m "Commit message"
   ```

   コミットメッセージには変更の概要や目的を記述します。

### **ブランチの作成と切り替え**

Gitでは、複数のブランチを作成して作業を分岐させることができます。

* ブランチの作成: 新しいブランチを作成するには、`git branch`コマンドを使用します。

  ```bash
  git branch new-branch
  ```
* ブランチの切り替え: 作業するブランチを切り替えるには、`git checkout`コマンドを使用します。

  ```bash
  git checkout new-branch
  ```

  または、`git switch`コマンドを使用します（Git 2.23以降）。

  ```bash
  git switch new-branch
  ```

### **コミットの修正と履歴の確認**

Gitでは、コミットの内容を修正したり、過去のコミット履歴を確認することができます。

* コミットの修正: 直前のコミットを修正するには、`git commit --amend`コマンドを使用します。

  ```bash
  git commit --amend
  ```
* 履歴の確認: コミット履歴を確認するには、`git log`コマンドを使用します。

  ```bash
  git log
  ```

  このコマンドにより、コミットのハッシュ、作者、日時、メッセージなどの情報が表示されます。

### **コミットの取り消しと変更の取り込み**

Gitでは、コミットを取り消したり、他のブランチやコミットから変更を取り込むことができます。

* コミットの取り消し: 直前のコミットを取り消すには、`git revert`コマンドを使用します。

  ```bash
  git revert HEAD
  ```
* 変更の取り込み: 他のブランチやコミットから変更を取り込むには、`git merge`コマンドを使用します。

  ```bash
  git merge other-branch
  ```

  または、`git rebase`コマンドを使用します。

  ```bash
  git rebase other-branch
  ```

これらのコマンドを使って、ローカルリポジトリの操作を行いましょう。注意してコマンドを実行し、変更を適切に管理しましょう。

### mergeとrebaseの違い

`merge`と`rebase`は、Gitにおいて異なるブランチの統合方法を表すコマンドです。以下にそれぞれの特徴と違いを説明します。

**merge（マージ）**

`merge`コマンドは、2つの異なるブランチの変更内容を統合するために使用されます。`merge`では、指定したブランチの変更内容を現在のブランチに取り込むことができます。統合された変更は新たなコミットとして履歴に残ります。

主な特徴：

* 統合された変更が明示的に残るため、ブランチの履歴が維持されます。
* 統合された変更が複数のコミットとして反映される場合があります。

**rebase（リベース）**

`rebase`コマンドは、現在のブランチのコミット履歴を別のブランチの先頭に移動するために使用されます。これにより、ブランチ間の履歴を直線的に整理することができます。

主な特徴：

* コミット履歴を整理し、直線的な履歴を作成します。
* 統合される変更は、新たなコミットとして履歴に追加されます。

`rebase`の使用には注意が必要であり、他の開発者との共同作業やリモートリポジトリへのプッシュ済みのコミットがある場合には慎重に行う必要があります。履歴の書き換えが発生するため、他の開発者の作業に影響を与える可能性があるためです。

どちらのコマンドを使用するかは、プロジェクトの特定の要件やチームのワークフローに応じて決定されます。一般的な原則として、`merge`は簡潔に変更を統合するために使用し、`rebase`はクリーンな履歴を維持するために使用します。ただし、特定の状況においてはそれぞれの利点とデメリットを考慮して判断する必要があります。

## **リモートリポジトリとの連携**

リモートリポジトリとの連携について、リモートリポジトリの作成と接続、リモートブランチの追跡、プッシュとプルの基本操作、マージとリベースの違いと利用方法、コンフリクトの解決とマージの手順について説明します。

### **リモートリポジトリの作成と接続**

リモートリポジトリを作成し、ローカルリポジトリと接続するためには、以下の手順を実行します。

1. リモートリポジトリの作成: リモートリポジトリを作成するためには、リモートホスティングサービス（例: GitHub、GitLab）上で新しいリポジトリを作成します。
2. ローカルリポジトリとの接続: ローカルリポジトリでリモートリポジトリとの接続を確立するために、以下のコマンドを使用します。

   ```bash
   git remote add origin <リモートリポジトリのURL>
   ```

   `origin`はリモートリポジトリへの参照名ですが、任意の名前を使用することができます。

### **リモートブランチの追跡**

リモートブランチを追跡し、ローカルブランチと同期するためには、以下の手順を実行します。

1. リモートブランチの追跡: リモートブランチを追跡するために、以下のコマンドを使用します。

   ```bash
   git checkout -b <ローカルブランチ名> <リモートリポジトリ名>/<リモートブランチ名>
   ```

   このコマンドにより、リモートブランチと同名のローカルブランチが作成され、リモートブランチとの追跡が開始されます。
2. リモートブランチの取得: リモートブランチの最新の変更を取得し、ローカルブランチと同期するために、以下のコマンドを使用します。

   ```bash
   git pull origin <リモートブランチ名>
   ```

   これにより、リモートブランチの変更がローカルブランチに反映されます。

### **プッシュとプルの基本操作**

プッシュとプルはリモートリポジトリとのデータの送受信に使用されます。

* プッシュ: ローカルの変更をリモートリポジトリに反映するために、以下のコマンドを使用します。

  ```bash
  git push origin <ローカルブランチ名>
  ```

  これにより、ローカルブランチの変更がリモートブランチに送信されます。
* プル: リモートリポジトリの変更をローカルに取り込むために、以下のコマンドを使用します。

  ```bash
  git pull origin <リモートブランチ名>
  ```

  これにより、リモートブランチの変更がローカルブランチに取り込まれます。

### **コンフリクトの解決とマージの手順**

コンフリクトは、マージやリベース時に複数の変更が衝突してしまった場合に発生します。以下はコンフリクトの解決とマージの手順です。

1. コンフリクトの発生: マージやリベースを実行すると、コンフリクトが発生する可能性があります。Gitは衝突箇所を自動的にマークします。
2. コンフリクトの解決: コンフリクトを解決するために、衝突した箇所を手動で編集し、変更を統合します。
3. マージの完了: 衝突を解決した後、変更をステージングし、マージを完了させます。

   ```bash
   git add <解決したファイル>
   git commit
   ```

これらのコマンドと手順を使用して、リモートリポジトリとの連携やブランチの操作、コンフリクトの解決を行うことができます。

## **チームでの共同作業**

チームでの共同作業について、ブランチの共有とプッシュ、プルリクエストの作成とレビュー、コードの統合とマージ、リモートブランチの削除とプルの更新、コミットメッセージのベストプラクティスについて説明します。

### **ブランチの共有とプッシュ**

複数の開発者が共同で作業するためには、各自が独立したブランチで作業し、変更内容をリモートリポジトリにプッシュする必要があります。

1. ブランチの作成: 各開発者は、新しい作業用ブランチを作成します。

   ```bash
   git branch feature-branch
   ```
2. ブランチのプッシュ: 各開発者は、自分の作業用ブランチをリモートリポジトリにプッシュします。

   ```bash
   git push origin feature-branch
   ```

   これにより、自分の作業用ブランチがリモートリポジトリに反映されます。

### **コードの統合とマージ**

作業用ブランチの変更内容をメインブランチに統合し、マージします。

1. マージの実行: プルリクエストが承認されたら、リモートリポジトリ上でマージ操作を実行します。
2. ローカルリポジトリの更新: メインブランチの変更内容を取り込むために、ローカルリポジトリで以下のコマンドを実行します。

   ```bash
   git pull origin main
   ```

   これにより、メインブランチの最新の変更がローカルリポジトリに反映されます。

### **リモートブランチの削除とプルの更新**

作業が終了し、不要になったリモートブランチを削除することがあります。

1. リモートブランチの削除: リモートリポジトリ上で不要な作業用ブランチを削除します。

   ```bash
   git push origin --delete feature-branch
   ```

   これにより、リモートリポジトリの作業用ブランチが削除されます。
2. プルの更新: リモートブランチが削除された場合、ローカルリポジトリで以下のコマンドを実行します。

   ```bash
   git pull origin
   ```

   これにより、リモートリポジトリの最新の変更がローカルリポジトリに反映されます。

### **コミットメッセージの例**

コミットメッセージは、変更内容を明確に伝えるために重要です。

* コミットメッセージは簡潔かつ明確にする。
* 変更の目的や意図を伝える。
* コミットメッセージには動詞の命令形を使用する（例: "Fix bug"、"Add feature"）。
* 複数の変更をまとめる場合は、関連する変更をグループ化し、メッセージをまとめる。

コミットメッセージのベストプラクティスとして、以下にいくつかの例を示します。

1. シンプルな変更の場合:

   ```
   Fix typo in README.md
   ```

   ```
   Update header styling in index.html
   ```

   ```
   Remove unused function in utils.js
   ```
2. 新機能や重要な変更の場合:

   ```
   Add user authentication feature
   ```

   ```
   Implement data validation for user inputs
   ```

   ```
   Refactor data access layer for improved performance
   ```
3. バグ修正の場合:

   ```
   Fix null pointer exception in User class
   ```

   ```
   Resolve issue with incorrect calculations in price calculation module
   ```

   ```
   Address XSS vulnerability in login form
   ```
4. 複数の変更をまとめる場合:

   ```
   Refactor user registration flow and improve error handling
   ```

   ```
   Update styling and add validation for user profile page
   ```

   ```
   Fix minor bugs and optimize database queries for better performance
   ```

これらの例は、コミットメッセージが簡潔で明確な内容を伝えることを示しています。変更の種類や目的が一目で分かるように、具体的な説明を含めることが重要です。また、適切な文法や命令形を使用することで、コミットメッセージが明確で読みやすくなります。変更の内容やプロジェクトの要件に合わせて、適切なコミットメッセージを作成してください。（**※自社内のプロダクトの場合、コミットメッセージは必ずしも英語のみで記載する必要はありません**）

以上の手順とベストプラクティスを使用して、チームでの共同作業を円滑に進めることができます。

## **Gitの応用**

Gitの応用について、タグの管理とリリースの作成、サブモジュールの利用と管理、履歴の検索とファイルのバージョンの特定、リベースとスカッシュの高度な使い方、Gitフックとカスタマイズの基礎について説明します。

### **タグの管理とリリースの作成**

* タグの作成: 特定のコミットに対してタグを作成するには、以下のコマンドを使用します。

  ```bash
  git tag <タグ名> <コミットハッシュまたはブランチ名>
  ```
* タグのリスト表示: リポジトリ内のタグを表示するには、以下のコマンドを使用します。

  ```bash
  git tag
  ```
* タグのプッシュ: リモートリポジトリにタグをプッシュするには、以下のコマンドを使用します。

  ```bash
  git push origin <タグ名>
  ```
* リリースの作成: リリースとしてマークされたタグを作成し、リリースノートを追加することで、プロジェクトのリリースを管理することができます。

### **サブモジュールの利用と管理**

* サブモジュールの追加: リポジトリ内にサブモジュールを追加するには、以下のコマンドを使用します。

  ```bash
  git submodule add <サブモジュールのリポジトリURL> <パス>
  ```
* サブモジュールの初期化: サブモジュールをクローンした後、初期化するためには、以下のコマンドを使用します。

  ```bash
  git submodule init
  ```
* サブモジュールの更新: サブモジュールの最新の変更を取得するためには、以下のコマンドを使用します。

  ```bash
  git submodule update
  ```

### **履歴の検索とファイルのバージョンの特定**

* 履歴の検索: コミットメッセージや変更内容をキーワードで検索するには、以下のコマンドを使用します。

  ```bash
  git log --grep=<キーワード>
  ```
* ファイルのバージョンの特定: 特定のファイルの変更履歴やバージョンを表示するには、以下のコマンドを使用します。

  ```bash
  git log -- <ファイルパス>
  ```

### **リベースとスカッシュ**

* リベースの使い方: ブランチのコミット履歴を他のブランチの先頭に移動するために、以下のコマンドを使用します。

  ```bash
  git rebase <ベースブランチ>
  ```
* スカッシュの使い方: 複数のコミットを一つにまとめるために、以下のコマンドを使用します。

  ```bash
  git rebase -i <ベースブランチ>
  ```

### **Gitフックとカスタマイズの基礎**

* Gitフック: Gitの特定のイベントが発生したときに自動的に実行されるスクリプトです。プロジェクトの特定の要件に合わせて、フックを作成してカスタマイズすることができます。
  * コミットフック: `pre-commit` フックや `post-commit` フックなど、コミットが行われたときに実行されるフックです。
  * プッシュフック: `pre-push` フックや `post-push` フックなど、プッシュが行われる前後に実行されるフックです。
* カスタマイズ: Gitの設定やエイリアスをカスタマイズすることで、作業の効率化や個人の作業スタイルに合わせた操作を行うことができます。

  ```bash
  git config --global alias.<エイリアス名> <コマンド>
  ```

これらのコマンドと機能を使用して、Gitの応用的な操作やカスタマイズを行うことができます。

## **Gitのベストプラクティスと今後の学習**

Gitのベストプラクティスと今後の学習について、ブランチ戦略とワークフローの選択、コンフリクトの予防と回避策、大規模プロジェクトの管理とGitの最適化、遠隔地での作業と競合の解決、一般的な問題のトラブルシューティング、今後の学習リソースについて説明します。

### **ブランチ戦略とワークフローの選択**

* ブランチ戦略: 開発フローに合わせたブランチ戦略を選択することで、複数の開発者が同時に作業する際の衝突や競合を回避し、効率的な作業を実現できます。代表的なブランチ戦略としては、Gitフロー、GitHubフロー、GitLabフローなどがあります。
* ワークフロー: チームの作業スタイルに応じたワークフローを選択し、プロジェクトの進行状況を管理します。例えば、フィーチャーブランチ、デベロップメントブランチ、リリースブランチなどの役割とルールを定義し、スムーズな作業を促進します。

### **コンフリクトの予防と回避策**

* コミットの頻度と範囲: 変更の範囲を小さくし、頻繁にコミットすることで、コンフリクトを予防します。また、変更の目的や意図を明確に伝えることで、他の開発者との認識のずれを減らします。
* 定期的なプルとリベース: リモートリポジトリからの最新の変更を定期的に取り込み、自分の作業ブランチをリベースすることで、競合や衝突を事前に回避します。

### **大規模プロジェクトの管理とGitの最適化**

* サブモジュールの使用: 大規模なプロジェクトでは、サブモジュールを使用してリポジトリを分割することで、複数の開発者が独立して作業することができます。
* Git LFSの使用: 大容量のファイルやバイナリファイルを効率的に管理するために、Git LFS（Large File Storage）を使用することができます。
* Gitの最適化: 大規模プロジェクトでは、Gitのパフォーマンスを最適化するための設定や最適なコマンドの使用方法を学ぶことが重要です。例えば、パックファイルの最適化や差分ファイルの圧縮などの設定を行うことができます。

### **遠隔地での作業と競合の解決**

* リモートリポジトリの使用: 遠隔地での作業では、リモートリポジトリを使用して複数の開発者がコードを共有し、変更を追跡することが重要です。
* プルとプッシュの注意: 遠隔地での作業では、定期的なプルとプッシュを行い、他の開発者の変更を取り込むことで、競合を予防します。

### **一般的な問題のトラブルシューティング**

* ローカルリポジトリの状態の確認: `git status` コマンドを使用して、ローカルリポジトリの状態を確認し、問題の原因を特定します。
* コンフリクトの解決: コンフリクトが発生した場合には、コンフリクトしたファイルを手動で編集し、競合を解消します。その後、コンフリクトをマークしてコミットします。

### **今後の学習リソース**

* 公式ドキュメント: Git公式サイト（<https://git-scm.com/doc）には、詳細なドキュメントとチュートリアルがあります。>
* Pro Git: Scott ChaconとBen Straubによる「Pro Git」は、Gitの詳細な解説書であり、オンラインで無料で利用できます。
* Gitコミュニティ: Gitのコミュニティやフォーラムに参加し、他の開発者との交流や問題解決に役立つ情報を得ることができます。
* プラットフォーム固有のリソース: GitHubやGitLabなどのプラットフォームは、Gitの活用に関する学習リソースやガイドを提供しています。

これらのベストプラクティスと学習リソースを活用することで、Gitの効果的な使用とプロジェクトの成功に向けてスキルを磨くことができます。
