【git stash】4つだけ！まずはこれを覚えよう

#結論
まずはこれを覚えましょう。

```
git stash save

git stash list

git stash pop

git stash drop
```
#git stashって何？

git stashは、「まだコミットしていない作業内容を一時的に避難させる」コマンドです。
例えば、作業ディレクトリでファイルを編集中に「急なタスクが入ってきて別のブランチで作業しなきゃ！でも手元の編集中のファイルは残しておきたいし、けどコミットできる段階じゃないし・・・」って時にはそう、"git stash"です。

git stashによって何が起きてるかというと下図みたいな感じです。
<img width="815" alt="gitstash.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583424/fa28fb3c-aad8-a966-b7b1-bebddd7edafe.png">
ご存じの通り、作業内容をgit addやgit commitやgit pushすることで図でいう右のほうに流れていきますね。
ところがgit stashはこの流れとは別の領域、"避難場所"を使用します。
コミットする前の作業内容をこの避難場所に置いておくことでいろいろ便利なことがあります。


この説明だけじゃ「結局何のこっちゃ？」だと思いますので具体的にコマンドを解説したいと思います。
###作業内容を一時的に避難させたい
```
git stash save
git stash
```
上図の青矢印の動きですね。
saveを省略したgit stashだけでも大丈夫です。
*Git管理下に置いてないファイル(=untrackedなファイル)はgit stash saveされないのでご注意！

またstashした内容がどんなものかわかるようにしておきたい方は、

```
git stash save "コメント"
```
このようにすればコメントを入れることができます。

####実演
どんな感じになるかちょっとやってみたいと思います。
いまの状況はgit statusするとこんな感じです。

```
PS C:\work\gitstash> git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   uno.txt

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:   dos.txt
```
手元には" uno.txt "と" dos.txt "というファイルがあり、
uno.txt はaddされてcommit待ちの状態で dos.txt はaddされてない状態です。

ではこれをコメントと一緒にgit stash saveしてみましょう。
コメントは"Change uno and dos"にします。

```
PS C:\work\gitstash> git stash save "Change uno and dos"
Saved working directory and index state On master: Change uno and dos
```
保存されたようですね。
この状態でgit statusするとどうなるでしょうか？やってみましょう。

```
PS C:\work\gitstash> git status
On branch master
nothing to commit, working tree clean
```
はい、というわけでaddされてcommit待ちのファイルとaddされてないファイルは手元からなくなったようです。
この状態であれば別ブランチに切り替えられますし、リモートリポジトリからgit pullすることが可能です。

でもstashしたものが本当に存在するのか不安になりますよね？
安心してください、ちゃんとコマンドがあります。

###stashした作業内容の一覧を確認したい
```
git stash list
```
これでstashした作業内容を確認できます。
ではさっそく先ほどの画面でコマンドを入力してみましょう。

```
PS C:\work\gitstash> git stash list
stash@{0}: On master: Change uno and dos
```
こんな感じでstashした内容がちゃんとあることを確認できました。
"Change uno and dos"というコメントもしっかり残っていますね。

今は1回しかstashしてないのでstash@{0}しかないですが、
たくさんstashするとその分stash@{0}, stash@{1}, stash@{2}...と溜まっていきます。
そうするとどれが何のstashかわからなくなるため、コメントを残されることをおススメします。

では次はstashした内容を作業ディレクトリに反映しましょう。

###stashした作業内容を反映したい
```
git stash pop stash@{n}
```
stash@{n}のnには反映したいstashの番号を入れてください。
今回の場合ですとn=0です。
それではgit stash popしてからgit stash listしたいと思います。

```
PS C:\work\gitstash> git stash pop stash@{0}
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:   dos.txt
        modified:   uno.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped stash@{0} (29f758e4d77ea2b17dcb38f607451b1b89f40a47)
PS C:\work\gitstash> git stash list
PS C:\work\gitstash> 
```
はい、これでstashしたものが作業ディレクトリに反映されて、stashした内容も消えています。

しかし、ここで一点注意です。
お気づきになられたかもしれませんが、" uno.txt "の場所がstash前後で変わっています。
stashする前の" uno.txt "はaddされてcommit待ちの状態でした。
しかしここではまたadd前の状態に戻っています。

もしstashした各ファイルを元の作業ディレクトリとインデックスにそのまま戻したい場合は下記になります。

```
git stash pop stash@{n} --index
```
stashした作業内容を反映するコマンドは他にもgit stash applyなどがございますが、
ここでは「4つだけ覚える」がテーマなので割愛します。

そしてお疲れさまでした。次が最後のコマンドです。

###stashした作業内容を削除したい
```
git stash drop stash@{n}
```
stashの指定方法はstash popと同じです。
指定したstash@{n}を削除することができます。
(参考：stash全てを削除したい場合はgit stash clear)

#おわりに
git stashって便利ですね。
気になる点として、「stashしたあとに手元で編集した内容がstashとコンフリクト起こしたらどうなるんだろー」って思いました。
けどそれはstashの使い方として正しくない気もしますね。
あくまでも一時的な"避難場所"と理解した上で使わないとですね。
今回まとめてみていい勉強になりました。

みなさんのご参考になったら嬉しいです。
もしよかったらコメントやいいねください！