gitについて自分のにわか知識を撲滅したい その2 add編

# gitについて自分のにわか知識を撲滅したい その2 add編

こちらは[ITRC Advent Calendar 2019](https://adventar.org/calendars/4759)の20日目の記事です。

前の人: [これで俺モ ゲンシジン
](https://qiita.com/rin1208/items/e28e501440de6601e95d)
次の人: [VyOS-1.2.0を使って簡単なネットワークを構築する話。クラウド接続編](https://hashy0917.wordpress.com/2019/12/21/vyos-1-2-0%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e7%b0%a1%e5%8d%98%e3%81%aa%e3%83%8d%e3%83%83%e3%83%88%e3%83%af%e3%83%bc%e3%82%af%e3%82%92%e6%a7%8b%e7%af%89%e3%81%99%e3%82%8b%e8%a9%b1%e3%80%82%e3%82%af/)

[gitについて自分のにわか知識を撲滅したい その1 基本編](https://qiita.com/cordingblue/items/3a3b00c27abcf84f501e)の続きです。

## 今回の目標

```git status```を駆使しながらaddで行っているとこを確認する。

## 目次

- git init
- git status
- git add (ステージングについて)
- git diff
- addのオプション

## git initでリポジトリの初期化

ディレクトリをgitで管理する際、```git init```というコマンドを使います。
```git init```はそのディレクトリをgitで管理するために.gitというサブディレクトリが生成されます。.gitはリポジトリに必要な骨組みの入ったディレクトリです。
しかしながらこの時点ではディレクトリは一切管理対象になっていません。

<details><summary>参考にした文章</summary><div>

> 既存のプロジェクトを Git で管理し始めるときは、そのプロジェクトのディレクトリに移動して次のように打ち込みます。

> ```$ git init```

> これを実行すると .git という名前の新しいサブディレクトリが作られ、リポジトリに必要なすべてのファイル (Git リポジトリのスケルトン) がその中に格納されます。 この時点では、まだプロジェクト内のファイルは一切管理対象になっていません
</div></details>

参照:[既存のディレクトリでのリポジトリの初期化
](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E5%9F%BA%E6%9C%AC-Git-%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%AE%E5%8F%96%E5%BE%97)

## git statusでディレクトリの状態を確認

```git status```はファイルの変更や状態を確認できるコマンドです。

一部だけですが便利なオプションは、

| オプション |    | 説明 |
| --- | --- | --- |
| -s (--short) |     | 短く表示してくれる。 |
| -b |     | 短い形式でもブランチと追跡情報を表示してくれる。(```git status -sb```で使う。) |

-sや-sb
オプションで表示されるMやAの意味は、

| 文字  | 意味  |
| --- | --- |
|'' | 未変更 |
| M | 変更 |
| A | 追加 |
| D | 削除済み |
| R | 名前変更 |
| C | コピー済み |
| U | 更新されたがマージされていない |
| ?? | 追跡されていない |
| !! | 無視 |

参照: [git-status](https://git-scm.com/docs/git-status)

## git addでステージングエリア送り

### まず状態について知る

作業ファイルはリポジトリをコピーして「作業コピー」を取得します。
その作業コピーに対して変更を加えてあげることで、変更内容のスナップショットをリポジトリにコミットします。

２つの状態があります。主語は変更されたモノです。(サブディレクトリとかファイルとか)

- 追跡されている(tracked)
- 追跡されてない(untracked)

#### 追跡されていない状態は

- initしたての状態
- cloneしたての状態
- 一度もcommitしていない新規ファイルを作成、変更した場合

つまり何も触ってないかったりする、ファイルの状態のこと。
```git status```や```git status -u```で確認できる。(-uはuntrackedという意味)

### 追跡されている(tracked)

- 「変更されていない(unmodified)」
- 「変更されている(modified)」
- 「ステージされている(staged)」

の状態に分けられる。

#### 「変更されていない(unmodified)」は

- commitしたての状態

#### 「変更されている(modified)」は

- 一度commitしたファイルに文字を入力したりして編集した状態

```git status```で確認した時、```modified```が赤色で表示されている。

#### 「ステージされている(staged)」は

- ```git add```した状態

```git status```で確認した時、```modified```が緑色で表示されている。

![staging](https://git-scm.com/book/en/v2/images/lifecycle.png)

<details><summary>参考にした文章</summary><div>

>これで、れっきとした Git リポジトリを準備して、そのプロジェクト内のファイルの作業コピーを取得することができました。 次は、そのコピーに対して何らかの変更を行い、適当な時点で変更内容のスナップショットをリポジトリにコミットすることになります。
作業コピー内の各ファイルには追跡されている(tracked)ものと追跡されてない(untracked)ものの二通りがあることを知っておきましょう。 追跡されているファイルとは、直近のスナップショットに存在したファイルのことです。これらのファイルについては変更されていない(unmodified)」「変更されている(modified)」「ステージされている(staged)」の三つの状態があります。 追跡されていないファイルは、そのどれでもありません。直近のスナップショットには存在せず、ステージングエリアにも存在しないファイルのことです。 最初にプロジェクトをクローンした時点では、すべてのファイルは「追跡されている」かつ「変更されていない」状態となります。チェックアウトしただけで何も編集していない状態だからです。
ファイルを編集すると、Git はそれを「変更された」とみなします。直近のコミットの後で変更が加えられたからです。変更されたファイルをステージし、それをコミットする。この繰り返しです。
</div></details>

### git diff コマンド

```git diff``` はファイルにテキストなどを追加したり、削除した場所が表示される。

```git diff --staged``` を使えば、次のcommitに含めるべくステージされた内容を知ることができます。

なお、直近のcommit以降のすべての変更を表示するわけではないことに注意が必要です。

```git diff --cached```と言うコマンドがありますが、```--staged```と一緒です。

ステージングエリア、インデックス、cachedは全て同じ意味であり、別名多すぎ問題なだけです。

### addのオプション

一部ですが記載しておきます。

| オプション |    | 説明 |
| --- | --- | --- |
| -u (--update) |     | 一度commitしたことあるファイル限定でファイルに変更があった場合addしてくれる |
| -A (--all) (--no-ignore-removal) |    | 全てaddしてくれる。 |
| -i (--interactive) |    | 対話型でaddしてくれます。 |
| -p (--patch) |    | ステージングエリアと作業ツリーの間のパッチを対話形式で選択し、ステージングエリアに追加します。 |
| -e (--edit) |    | テキストエディタで変更されたファイルの内容を書き換えられます。 |

```git add .``` は ```git add -A``` と変更されたファイルをaddするという動作が同じです。

```git add -i``` はこのようになっております。

```
$ git add -i

*** Commands ***
  1: status	  2: update	  3: revert	  4: add untracked
  5: patch	  6: diff	  7: quit	  8: help

What now> 8

status        - show paths with changes
update        - add working tree state to the staged set of changes
revert        - revert staged set of changes back to the HEAD version
patch         - pick hunks and update selectively
diff          - view diff between HEAD and index
add untracked - add contents of untracked files to the staged set of changes
```

以下コマンドの意味です。

| コマンド |    | 説明 |
| --- | --- | --- |
| status |    | statusの確認。```git status```と同じ。 |
| update |    | 一度commitしたことあるファイル限定でファイルに変更があった場合addしてくれる。```git add -u```と同じ。 |
| revert |    | ステージングエリアからだけファイルを削除してくれる。addされてない状態に戻る。 |
| patch |    | ```git add -p```を起動。 |
| diff |    | 変更した差分の確認。```git diff```と同じ。 |
| add untracked |    | 変更した全てのファイルをaddする。```git add -A```と同じ。 |

個人的に驚いたのがrevertです。間違えてaddした時用の対策が対話モードで実装しているなんて知らなかったからです。



```git add -p```はこのようになっております。
README.mdというファイルに4行変更を追加したものをファイルの例にします。

```
$ git add -p

diff --git a/README.md b/README.md
index 省略
--- a/README.md
+++ b/README.md
@@ -1 +1,4 @@
 # test
+
+- ```-p```
+
(1/1) Stage this hunk [y,n,q,a,d,e,?]? 
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
e - manually edit the current hunk
? - print help
@@ -1 +1,4 @@
 # test
+
+- ```-p```
+

```

以下コマンドの意味です。

| コマンド |    | 説明 |
| --- | --- | --- |
| y |  | addする |
| n |  | addしない |
| q |  | 終了する |
| a |  | 対象のディレクトリから下をaddする |
| d |  | 対象のディレクトリから下をaddしない |
| e |  | ```git add -e```と同じ |
| ? |  | helpをみる |

## まとめ

- initで初期化
- statusで状態確認
- 状態は大きく分けて追跡されている(tracked)、追跡されてない(untracked)がある。
- また、追跡されている(tracked)状態は「変更されていない(unmodified)」「変更されている(modified)」「ステージされている(staged)」の3つがある。

## 参考

[git 日本語](https://git-scm.com/book/ja/v2)
[git-add](https://git-scm.com/docs/git-add)
[Git の基本 - 変更内容のリポジトリへの記録](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E5%9F%BA%E6%9C%AC-%E5%A4%89%E6%9B%B4%E5%86%85%E5%AE%B9%E3%81%AE%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%B8%E3%81%AE%E8%A8%98%E9%8C%B2)