Gitの基本とGit Bash

# はじめに

最近Gitに初めて触れたのだが、仕組みや用語の理解に時間がかかった。
そのため、今回記事に書くことで自分自身の理解を深めるとともに、
私と同じようにGitに不慣れな人への助けになればと考え、書かくこととなった。

## Gitとは
- ネット上に無料で公開されているオープンソースソフトウェア
- ファイルのバージョンを管理する「分散型バージョン管理システム」
- バージョン管理が楽になるので、ファイルに変更を加えたり、修正がしやすくなる
- GitHabやGitLab等のWeb上に提供されているサービスと連携できる
- リモートリポジトリと手元のローカルリポジトリでファイルを別々に管理

**※バージョン管理システムとは**
　「誰が」「いつ」「何を」変更したのかをファイルごとに記録するシステム
　記録をもとに、過去の特定の状態を復元することができる
　どのタイミングでバグが発生したのか追跡することもできる

## Gitの仕組み
### Gitのフロー

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052041/34ee38be-4a8c-44d3-93c6-f164bc7980fa.png">

- Gitで複数人同時進行の作業をする様子を図で表すと分散したような形になるため、
**"分散型"** バージョン管理システムと呼ばれる

### Gitの特徴
- 基本、CUI(コマンドベース)のため、画面ベースのソフトは別々にPCに入れる
- 基本、ブランチやコミット履歴等を画面で分かりやすく見るには別のウェブ上のサービスが必要
    
## 基本用語
#### リポジトリ
- ファイルやディレクトリを格納するための保管庫
- IT分野において、情報や成果物を蓄積・管理し、開発プロセスを効率化するうえで重要な役割を担う
- ローカルとリモートの2つある

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052041/470f1552-2903-46b4-839e-b52aad4049c9.png">
    
#### リモートリポジトリ
- 特定のサーバー上に設置された共用リポジトリ
- 全体の作成物をまとめる
#### ローカルリポジトリ
- 各作業端末に設置された個別リポジトリ
- 個人の作業内容を他の作業者に共有する場合、リモートにデータを送信(push)する
- 他の作業者の作業内容を見るには、リモートのデータを受信(fetch)する
    
#### フェッチ(fetch)
- リモートリポジトリのデータをローカルリポジトリに受信すること
- 他の作業者の作業内容を見るときに行う
    
#### プッシュ(push)
- ローカルリポジトリのデータをリモートリポジトリに送信すること
- 個人の作業内容を他の作業者に共有するときに行う
    
#### インデックス
- リポジトリとワークツリーの中間領域
- 複数個ファイルをまとめてローカルリポジトリに移す(commit)ことができる
- インデックスへの登録は **"ステージング"** とも呼ばれる

<img width="170" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052041/a3bd0bd9-e15c-4678-b026-675eaab9ef71.png">
    
- 各作業者が作業をしているディレクトリのこと
- ワークツリーで編集した内容を各種リポジトリに移すには、インデックスへの登録(add)が必要
- リポジトリからワークツリーへの反映は自動で行われる
    
#### アッド(add)・ステージング
- インデックスへ登録すること
    
#### コミット(commit)
- インデックスからローカルリポジトリへの記録作業
- コミットのたびに、以下のような情報が記録される
    - ファイルの変更内容
    - ファイルの編集日時
    - コミットした人（名前・メールアドレス）
    - コミットメッセージ（任意）
    
- コミットのたびに上記の情報を持ったファイルが生成され、リポジトリに格納される
- リポジトリ上でコミットの履歴を確認することができる（コミットログ）
    
#### クローン(clone)
- リモートにあるリポジトリをローカルにコピーする
- 一般的には、開発環境構築のためにローカルに作業ディレクトリを作る目的で行われる
- 完全なコピーなので、リモートリポジトリのサーバーが壊れても、ローカルリポジトリに対してリモートのサーバーからクローン(clone)すれば復元することが可能

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052041/779d796c-57d4-4aaf-92f6-c673bbb78c65.png">

#### ブランチ
- 作業者間の平行作業を全て正確に記録するための機能
- ブランチの情報はリポジトリに保存されている
- コミットのフローを分岐させることで実現している
- 複数のブランチを１つにまとめる(merge)ことでシステムを開発していく

<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052041/39103933-1b61-41f9-a904-e012acfdcc4a.png">
    
#### マージ(merge)
- 複数のブランチを１つにまとめること
    
#### オリジン(origin)・マスター(master)
- オリジナル（元々）のブランチのこと
**※基本的にこのブランチはマージのとき以外に操作しない**
    
#### プル(pull)
- ローカルリポジトリは自動的にリモートの内容を取得しない
そのため、リモートから情報を受信(fetch)し、ローカルリポジトリのブランチの更新(merge)を行うことで更新できる
(Fetch + marge = pull)
- ローカルリポジトリのブランチが更新されることで、ワークツリーのファイルが自動更新されることから、リモートリポジトリをもとにワークツリーを更新することをプル(pull)と表現することもある
- 最新データに更新するときに行う

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052041/867e26ed-b3bf-4537-829f-d79bfa5c7d3b.png">

#### カレントブランチ
- 現在作業中のブランチを指す

## Gitの使い方
1. 複数人で作業する際は、リモートリポジトリに作業内容を共有、またはリモートリポジトリから引用する
2. リモートリポジトリにデータを送るには、ローカルリポジトリを経由しなければならない
3. そのために、各端末ごとにフォルダを設置し、作業者はそのフォルダ内にファイルを作成し、作業をする
4. 編集内容をフォルダからローカルリポジトリに移すために、中間にあるインデックスへ登録する
5. その後、インデックスからローカルリポジトリに記録するが、その編集内容をコメントとして残しておくと、確認した際に分かりやすい
6. リモートからローカルリポジトリへデータを受信すると、他の作業者の内容を閲覧、保存ができる
7. 作業を始める時と、ローカルからリモートリポジトリへデータを送信する前には、リモートリポジトリからデータを受信し最新状態へ更新をしておく
→その結果、競合を減らし、効率化を図る

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4052041/34ee38be-4a8c-44d3-93c6-f164bc7980fa.png">

## Gitと連携する
- Gitはツールやソフトウェアを活用したり、Web上に提供されているサービスと連携したりすることで、使用できる

- Gtiを使うためのツールやサービス
    - SourseTree
        - GitをGUI(画面ベース)で使用できるソフトウェア
        - 同時に入れてくれるため手軽に使える
        - これ一つでGitを使え、更にブランチや他者のコミットの履歴を画面ベースで見ることができる
        
    - GitHub/GitLab
        - ネットワーク上に公開されている基本無料のウェブサービス
        - ネット上でプログラムソースや情報を共有したり公開することができる
        (リモートリポジトリとして利用することが多い)
        - 他の人が公開したものをネット上で見ることができる
        - 開発現場でもよく利用されている(その場合は非公開で管理)
        
    - GitBash
        - GitをCUI(文字ベース)で使用できるツール
        - Linuxコマンドを打ち込むことで様々な命令を出すことができる
        - 実際の開発現場でもよく使われており、細かな操作やスクリプトの実行にも対応
        - Windows環境でも利用できるため、開発の学習にも便利

#### **※今回はより深く学習した、GitBashについて説明を行う**
    
## Git Bashを使う
#### インストール
1. ダウンロード
下記URL先でダウンロードをクリック
[Git Bash](https://gitforwindows.org/ "ダウンロードページ")
2. ダウンロードしたファイルの実行
全て“Next”を押して進める
    
#### 設定
コミット等の際に表示されるユーザー名とメールアドレスを登録する
    
1. ユーザー名、メールアドレスを設定
「`git config --global user.name [ユーザー名]`」：ユーザー名の設定
「`git config --global user.email [メールアドレス]`」：メールアドレスの設定

2. 設定の確認
「`git config --global --list`」：設定した内容を表示

~~~terminal:gitbash
$ git config -- global user. name ユーザー名

$ git config -- global user. email メールアドレス

$ git config -- global -- list
user.name=ユーザー名
user. email=メールアドレス
~~~

:::note
ユーザー名、メールアドレスが表示されたら登録完了
:::
        
## 実際の操作・コマンド

:::note warn
何か作業を行ったらコマンドを打ってこまめにに確認する
:::

#### リポジトリの作成
作業に使用するローカルリポジトリの作成

1. 作業フォルダの作成
「`cd [アドレス]`」：作成したいアドレスに移動
「`mkdir [フォルダ名]`」：フォルダの作成
フォルダ名は任意の名前（今回はGit）

2. 作成したフォルダへの移動
「`cd [フォルダ名]`」：フォルダの移動

3. リポジトリの作成
「`git init`」：空のリポジトリを作成
「`ls –a`」：フォルダの中身を表示する

~~~terminal:gitbash
$ cd /c/

$ mkdir Git

$ cd Git

$ git init
Initialized empty Git repository in C:/Git/.git/

$ 1s -a
/ .. / .git/
~~~

:::note
作成した名前のファイルができていれば作成完了
:::

#### インデックスに登録する
まずコミットを行う作業ファイルの作成をする

1. ファイルの作成とリポジトリの状態を確認
「`touch [ファイル名]`」：ファイルの作成
今回は(test.txt)
「`git status`」：リポジトリの状態を確認

**※「git status」の表示内容について**
・On branch master
ブランチの情報が表示されている
現在のブランチが ”master“ であることが分かる
・No commit yet
一度もコミットしていない場合に表示される
・Untracked files
Gitの管理対象になっていないファイルを表示しする

~~~terminal:gitbash
$ touch test.txt

$ git status
On branch master

No commits yet

Untracked files:
(use "git add <file> ... " to include in what will be committed)
test.txt

nothing added to commit but untracked files present (use "git add" to track)
~~~

2.インデックスにファイルを登録をする
「`git add [ファイル名]`」：指定したファイルをインデックスに登録

**※「git add .」　全てのファイルをインデックスに登録できる
※「git reset」　インデックスの登録を取り消すことができる**

「`git status`」：ファイルの状態を確認

**※Change to be committed に緑でインデックスに登録済みのファイルが表示される
※Qiitaの表示上色が付かなかったが(test.txt)が緑色**

~~~terminal:gitbash
$ git add test.txt

$ git status
On branch master

No commits yet

Changes to be committed:
(use "git rm -- cached <file> ... " to unstage)
      new file:   test. txt
~~~

:::note
Change to be committed と表示されたら登録完了
:::

#### コミットする
インデックスに登録されているファイルをコミットする

1. ファイルのコミットを行う
「`git commit -m “コメント”`」：コミットする
今回は”テストファイルのコミット”とコメント

~~~terminal:gitbash
$ git commit -m"テストファイルのコミット"
[master (root-commit)437129f]テストファイルのコミット
1 file changed, 0 insertions(+), 0 deletions (-)
create mode 100644 test.txt
~~~

2.コミット後の確認を行う
「`git status`」：状態の確認

**※nothing to commit, working tree clean と表示される**
全てコミットされ、その後の変更されたファイルが無い状態に表示される

~~~terminal:gitbash
$ git status
On branch master
nothing to commit, working tree clean
~~~

:::note
nothing to commit, working tree clean と表示されたら登録完了
:::

3.コミットの履歴を確認
「`git log`」：履歴を確認

 **※履歴には以下の内容が表示される**
・commit：「コミットハッシュ」　（コミットを特定することができる値）		
・Author：「コミットしたユーザー」		
・Date：「コミットの日時」
・Dateの下に 「コメント」 が表示される

~~~terminal:gitbash
$ git log
commit 437129f31c1ff6df15f5da18cc5676b1e9cfe408 (HEAD -> master)
Author: ユーザー名 <メールアドレス>
Date: Wed Apr 13 15:39:09 2022 +0900

        テストファイルのコミット
~~~

#### コミット後のファイル変更
コミットしたファイルに編集を加える

1. ファイルの編集・変更
「`vi [編集ファイル名]`」：ファイルを開く
今回は（test.txt）
「`i`」：ファイルを編集
**※入力後編集可能になる**
Escキー：編集を終了
「`:wq`」：編集を保存、戻る
「`git status`」：状態を確認 
**※Changes not staged for commit に赤色で変更のあったファイルを表示する
※Qiitaの表示上色が付かなかったが(test.txt)が赤色**

~~~terminal:gitbash
$ vi test.txt

$ git status
On branch master
Changes not staged for commit:
(use "git add <file> ... " to update what will be committed)
(use "git restore <file> ... " to discard changes in working directory)
      modified:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")
~~~

2.差分の確認
「`git diff`」：コミットした内容から変更されている箇所が表示される

~~~terminal:gitbash
$ git diff
diff -- git a/test.txt b/test. txt
index e69de29 .. 0867e73 100644
a/test.txt
+++ b/test.txt
ca -0,0 +1,3 ca
+test
+test
+test
~~~

3.変更内容の取り消し
「`git checkout -- [ファイル名]`」：ワークツリーでの変更を取り消す

**※変更を取り消したため、「git diff」を使用しても何も表示されない**

~~~terminal:gitbash
$ git checkout -- test.txt

$ git diff

$
~~~

:::note
何も表示されなければ取り消し完了
:::

#### ブランチ
ブランチを操作する

1. ブランチの作成
「`git branch [ブランチ名]`」：ブランチの作成を行う
今回は(test_branch)
「`git branch`」　ブランチの状態を確認する
カレントブランチは緑色で「*」が表示される
**※Qiitaの表示上色が付かなかったが(master)が緑色**

~~~terminal:gitbash
$ git branch test_branch

$ git branch
* master
  test_branch
~~~

2.ブランチの切り替え
「`git checkout [ブランチ名]`」：ブランチの切り替えを行う
「`git branch`」：ブランチの状態を確認する
**※Qiitaの表示上色が付かなかったが(test_branch)が緑色**

~~~terminal:gitbash
$ git checkout test_branch
Switched to branch 'test_branch'

$ git branch
  master
* test_branch
~~~

3.ブランチの削除
「`git checkout [ブランチ名]`」：ブランチの切り替えを行う
（カレントブランチは削除できないため）
「`git branch –D [ブランチ名]`」：指定したブランチの削除を行う
「`git branch`」：ブランチの状態を確認する

~~~terminal:gitbash
$ git checkout master
Switched to branch 'master'

$ git branch -D test_branch
Deleted branch test_branch (was ef93224).

$ git branch
* master
~~~

:::note
削除したブランチが消えていたら登録完了
:::

# まとめ・コマンド一覧
### まとめ
・Gitとは、ネット上に無料で公開されているオープンソースソフトウェアで、ファイルのバージョンを管理する「分散型バージョン管理システム」と呼ばれる
・バージョン管理が楽になるので、ファイルに変更を加えたり、修正がしやすくなる
・GitHabやGitLab等のWeb上に提供されているサービスと連携できる
・リモートリポジトリと手元のローカルリポジトリでファイルを別々に管理
・Git Bashでは、何か作業を行ったらコマンドでこまめにに確認するとよい

上記が、私が調査しまとめた結果となる。
今後も学習を続けより理解を深めていこうと考える。

### Git Bashのコマンドを使った基本操作
<table>
    <caption>基本コマンド</caption>
    <thead>
        <tr>
            <th>コマンド</th> <th>説明</th>
        </tr>
    </thead>
    <tr>
        <td>git config --global --list</td> <td>設定の確認</td>
    </tr>
    <tr>
        <td>cd</td> <td>フォルダの移動</td>
    </tr>
    <tr>
        <td>ls –a</td> <td>フォルダの中身を表示</td>
    </tr>
    <tr>
        <td>git status</td> <td>リポジトリの状態を確認</td>
    </tr>
    <tr>
        <td>git log</td> <td>コミットの履歴を確認</td>
    </tr>
    <tr>
        <td>git diff</td> <td>差分を表示</td>
    </tr>
    <tr>
        <td>git branch</td> <td>ブランチの状態を確認</td>
    </tr>
    <tr>
        <td>git checkout ブランチ名</td> <td>ブランチの切り替え</td>
    </tr>
</table>

### 作業コマンド
<table>
    <caption>作業コマンド</caption>
    <thead>
        <tr>
            <th>コマンド</th> <th>説明</th>
        </tr>
    </thead>
    <tr>
        <td>git config --global user.name [ユーザ名]</td> <td>ユーザー名を設定</td>
    </tr>
    <tr>
        <td>git config --global user.email [メールアドレス]</td> <td>メールアドレスを設定</td>
    </tr>
    <tr>
        <td>mkdir [フォルダ名]</td> <td>作業フォルダの作成</td>
    </tr>
    <tr>
        <td>git init</td> <td>リポジトリの作成</td>
    </tr>
    <tr>
        <td>touch [ファイル名]</td> <td>コミットするファイルの作成</td>
    </tr>
    <tr>
        <td>git add [ファイル名]</td> <td>インデックスにファイルの登録</td>
    </tr>
    <tr>
        <td>git commit -m “コメント”</td> <td>ファイルのコミットを行う</td>
    </tr>
    <tr>
        <td>vi [編集ファイル名]</td> <td>ファイルの編集</td>
    </tr>
    <tr>
        <td>git checkout -- [ファイル名]</td> <td>変更内容の取り消し</td>
    </tr>
    <tr>
        <td>git branch [ブランチ名]</td> <td>ブランチの作成</td>
    </tr>
    <tr>
        <td>git branch –D [ブランチ名]</td> <td>ブランチの削除</td>
    </tr>
</table>