【Git】stashコマンドのまとめと使い方 〜変更差分の一時退避〜

「間違えて違うブランチで作業していることに気づいた..」
「作業途中で別のブランチでの作業を頼まれた」<br>

みたいなときに役に立つstashコマンドの使い方のサラッと纏めです。
これを使うと「作業している変更差分を一時的に退避して、別のブランチに反映させる」ということができます。

最初にコマンド一覧表をまとめつつ、
そのあとに各コマンドの使い方を補足していく構成です。

# | Stashコマンドまとめ
## ①退避する系
|コマンド|効果・効能|
|:--|:--|
|$ git stash|シンプルに退避する（既定）|
|$ git stash -u|シンプルに退避する（untrackedファイルも含む）|
|$ git stash -a|シンプルに退避する（さらにignoredファイルも含む）|
|$ git stash save "メッセージ"|メッセージ付きで退避する（既定）|
|$ git stash save -u "メッセージ"|メッセージ付きで退避する（untrackedファイルも含む）|
|$ git stash save -a "メッセージ"|メッセージ付きで退避する（さらにignoredファイルも含む）|

## ②退避を反映させる系
|コマンド|効果・効能|
|:--|:--|
|$ git stash list|退避の一覧を見る（反映前の準備として）|
|$ git stash pop|最新の退避を現在のブランチに反映させる（退避リストからは削除）|
|$ git stash apply|最新の退避を現在のブランチに反映させる（退避リストに残す）|
|$ git stash apply 'list番号'|指定した退避を現在のブランチに反映させる|

## ③退避の差分を調べる系
|コマンド|効果・効能|
|:--|:--|
|$ git stash show|最新の退避の差分の要約を見る|
|$ git stash show 'list番号'|指定した退避の差分の要約を見る|
|$ git stash show -p|最新の退避の差分を詳しく見る|
|$ git stash show -p 'list番号'|指定した退避の差分を詳しく見る|

## ④退避を削除する系
|コマンド|効果・効能|
|:--|:--|
|$ git stash drop|最新の退避を削除する|
|$ git stash drop 'list番号'|指定した退避を削除する|
|$ git stash clear|全ての退避を削除する|

# | Stashコマンドたちの詳しい使い方
では上記の一覧のコマンドの使い方を、順番に詳しくみていきます。
## ①退避させるコマンド
### ・シンプルに退避する
まずは最もシンプルに退避するパターンです。

```sh
$ git stash
```
これでコミットしていないローカルの変更差分を退避させることができます。
ただし、未追跡ファイル(untracked)や無視されたファイル(ignored)は含まれません。

つまりstashされるのは..<b>
・git addされている変更
・まだgit addしてないけど追跡はしているファイルの変更
</b>です。
<font color="SteelBlue">※ ファイルを新規追加した時などはご注意ください</font>

### ・シンプルに退避する(untrackedファイルも含む)
`-u`オプションを付けることで、未追跡のファイル(untracked)も含めて退避できます。

```sh
$ git stash -u
```
`-u`は`--include-untracked`というロングオプションの略です。

### ・シンプルに退避する(さらにignoredファイルも含む)
`-a`オプションを付けることで、未追跡のファイル(untracked)および無視ファイルされたファイル(ignored)を含めてすべて退避できます。

```sh
$ git stash -a
```
こちらは`--all`の略なのでイメージしやすいですね。

### ・メッセージ付きで退避する
第二引数に`save`を加えると、その後ろにメッセージを追加することができます。

```sh
$ git stash save "メッセージ"
```
後で退避リストにを見たときにわかりやすいように、メッセージ付きで退避させるのがオススメです。
(すぐに消す一時的な退避であればメッセージなしでもOKです)

### ・メッセージ付きで退避する(untrackedファイルも含む)
上記を組み合わせて、未追跡のファイル(untracked)も含めてメッセージ付きで退避させるパターンです。

```sh
$ git stash save -u "メッセージ"
```
もちろん`-a`で無視ファイルも含めてメッセージ付き退避もできます。

```sh
$ git stash save -a "メッセージ"
```
<br>
## ②退避を反映させるコマンド
### ・(準備1) まずブランチを切り替える
退避を反映させる前に、ブランチを確認して切り替えましょう。

```sh
$ git branch #現在のブランチを確認
$ git checkout <ブランチ名> #ブランチを切り替え
```
### ・(準備2) 退避の一覧を確認する
`$ git stash list`コマンドで、現在退避されているリストを確認することができます。

```sh
$ git stash list
stash@{0}: On main: 〇〇を修正
stash@{1}: On main: xxを修正
stash@{2}: On main: △△を修正
```
なおこれらはローカルだけの物なので、pushしてもリモートに反映されることはありません。
(`stash`は「隠し場所」という意味なので、なんとなくしっくりきますね。)

### ・最新の退避を反映させる（リストからは削除）
いちばんシンプルな反映コマンドです。

```sh
$ git stash pop
```
これで最新の退避が現在のブランチに反映されつつ、退避一覧からは削除されます。

### ・最新の退避を反映させる（リストにそのまま残す）
こちらも最新の退避を現在のブランチに反映させるコマンドですが、退避リストからは削除されずにそのまま残ります。

```sh
$ git stash apply
```
リストに残るので、複数のブランチに反映させたいときなどに便利ですね。

### ・指定した退避を反映させる
退避リストの中から指定したものを反映させたいときに使います。

```sh
$ git stash apply <list番号>
```
この`<list番号>`は退避リストの何番の退避を反映させるかを指定します。
例えばリストが、

```sh
$ git stash list
stash@{0}: On main: 〇〇を修正
stash@{1}: On main: xxを修正
stash@{2}: On main: △△を修正
```
こんな感じになっていて、真ん中の「xxを修正」という退避を反映したい場合は

```sh
$ git stash apply 1
```
のように指定します。
(こちらも退避リストからは削除されずにそのまま残ります)

番号の指定は、

```sh
$ git stash apply stash@{1}
```
でもOKです。
なお先ほどの`$ git stash pop`でも同じように退避を指定して反映することができます。
<br>

## ③退避の差分を調べるコマンド
### ・退避の差分の要約を見る
`git stash show`を使うと、どのくらい変更したかの要約を表示することができます。

```sh
$ git stash show
 User.php | 1 +
 app.js | 3 +++
 2 files changed, 4 insertions(+)
```
`$ git diff --stat`のような感じですね。

### ・退避の差分を詳しく見る
`-p`オプションを付けると、通常の`$ git diff`のように差分を詳しく表示することができます。

```sh
$ git stash show -p
```
メッセージ付きで退避していればそんなに出番はないかなぁという気もします。
なお先ほどの退避反映のときと同じように、退避を指定して差分を確認することができます。
<br>

## ④退避を削除するコマンド
### ・最新の退避を削除する
```sh
$ git stash drop
```
これで退避リストの最新のものが削除されます。

### ・指定した退避を削除する
```sh
$ git stash drop <list番号>
```
list番号の指定方法は先ほどと同じです。

### ・退避を全て削除する
```sh
$ git stash clear
```
これを実行すると現在退避してあるリストを全て削除することができます。
間違えて実行しないように。。
<br>

以上、備忘録的な記事ではありますが少しでもお役に立てば嬉しいです。