Git、ステージングやコミットしたあとの取り消しコマンド

#git reset コミットを取り消す
**reset**
>コミット履歴を遡り、それ以降のコミット全てを無かったことにする。

>後述の**revert**の場合は取り消しも履歴に残るので、**取り消しの取り消しが出来る**が、**reset**はそれが**出来ない**。

要するに**$git add**でステージングに追加するの逆。
ステージングしたファイルを取り消す。

- --hardオプション
直前のコミット時と**完全に一致した状態に戻る**
ワーキングディレクトリでの作業中の物がが全て無かったことになる。

```php
/** 
 * 現在のブランチの位置を<commit id>まで戻す。
 * ただしワーキングディレクトリの状態はそのまま。
 */
$ git reset <commit id>

/**
 * 上記に加えhardオプションを加えると、ワーキングディレクトリの作業内容も消え、
 * 指定したIDの時点での状態に戻される。
 */
$ git reset -- hard <commit id>

```

※**reset**は、reset自体の取り消しを後から出来ないので、ローカルで編集中の物や、resetで取り消されるコミット済の内容を完全に捨ててOKな時に使う事。


#単純にresetしてみる
まず適用に新規ファイルを作りステージングに追加する。
その後それを取り消す。

**以下を新規作成**
`resetTestFolder
fileA.txt`

```text:fileA.txt
1st value
```

```php
// フォルダごとステージングに追加
$ git add resetTestFolder/

// ステージングされている状態の確認
$ git status

On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   resetTestFolder/fileA.txt

```

この状態からテキストファイルの内容を書き換える。
（ステージングには追加しないので、ワーキングディレクトリとステージングエリアで差異が出来ている状態にする）


```text:fileA.txt
内容を書き換えてみる
```

```php
$ git status

On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   resetTestFolder/fileA.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   resetTestFolder/fileA.txt
```

```php
$ git reset fileA.txt
```


```text:fileA.txt
内容を書き換えてみる
```

ステージングに追加したとの編集は残る。

#ステージング側の内容で上書きつつステージングを取り消す
まずは下記のようなファイルがステージングされている状態。

```php
$ git status

On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   fileA.txt
```

```text:fileA.txt
内容を書き換えてみる
```

**ワーキングディレクトリのファイルの内容を下記に書き換える**

```text:fileA.txt
内容を書き換えてみる

ステージングエリアに登録したあとにファイルを編集してみる。
このあとこの追加した内容は消される想定。
```

```php
$ git status

On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   fileA.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   fileA.txt
```

教本によると

1. **checkout \<file>**を使いステージング内容でワーキングディレクトリを上書き
2. ステージングエリアへの登録内容を**rn --cached \<file>**で取り消す
　（ここは前述の**reset**でもいいらしい）

なんか回りくどい気がするけどやってみよう。

```php
$ git checkout fileA.txt
```

```text:fileA.txt
内容を書き換えてみる
```

追加した行が消えたね。
（ただこれだとステージングの内容なのか、直近の編集を無かったことにしたのかとか、厳密には判断付かないテストだった・・・）

で、今度はステージングの取り消し

```php
$ git rm --cached fileA.txt
rm 'resetTestFolder/fileA.txt'

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        ./

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

#reset と rm --cached はどちらを使うべき？
**rm**は本来ファイルをワーキングディレクトリとステージングエリアから削除するらしい。
怖いから**reset**の方がいいかなぁ？