# 作業中にやらないといけないことが発生した時

git stash をよく使っているので簡単にまとめます。

# git stash を使いたくなるとき

だいたい、何かしら作業中にやらないといけないことが発生したときです。

  • 作業中に、他のタスクに対応しないといけなくなったとき
  • 作業中に、レビューをしないといけなくなったとき
  • 別ブランチに commit 前の変更を移したいとき

# git stash とは

一時的に変更を退避させるもの。

# こんな感じで使ってます

# いったん作業を退避させたい時

<!-- 変更中(commit はまだしてない) -->
<!-- いったん別の作業したい! -->
$ git stash save -u xx変更途中

<!-- 別の作業 -->
<!-- xx変更途中の作業に戻りたい! -->
$ git stash list
...
stash@{xx}: On branch-name: xx変更途中
...

<!-- xx変更途中を適用する -->
$ git stash pop xx

# 実装に迷っている時

<!-- 変更中(commit はまだしてない) -->
<!-- うーん、この実装よくないかも、 -->
<!-- 最初から実装したいけど、この作業残しておきたい、 -->
$ git stash save -u 納得してない実装

<!-- はじめから作業 -->
<!-- 良い実装ができた! -->
$ git add .
$ git commit -m '良い実装'

<!-- stash した 納得してない実装 を削除しておこう -->
$ git stash list
stash@{0}: On branch-name:  納得してない実装
...

<!-- 削除 -->
$ git stash drop
<!-- or -->
$ git stash drop 0

# 別ブランチで作業をはじめてしまった時

<!-- 変更中(commit はまだしてない) -->
<!-- masterブランチで作業しちゃってた、、 -->
$ git stash save -u git-stashブランチで作業したかった

<!-- ブランチ切り替え -->
$ git checkout -b git-stash

<!-- 途中の作業を適用させたい -->
$ git stash list
stash@{0}: On master: git-stashブランチで作業したかった
...

<!-- git-stashブランチで作業したかったのブランチに適用する -->
$ git stash pop
<!-- or -->
$ git stash pop 0

# git stash の使い方(詳しく)

あるファイルの変更中、

$ git diff
diff --git a/src/pages/about.md b/src/pages/about.md
index 00ed8d6..8d59a06 100644
--- a/src/pages/about.md
+++ b/src/pages/about.md
@@ -7,3 +7,5 @@ permalink: /about
 # About

 エンジニアっぽいことをしている人
+
+テスト

いったんこの変更を退避しておいて、 別の作業をしたくなった場合、

$ git stash save
Saved working directory and index state WIP on blog/2019-02-02: 8d5e7e6 rb -> ruby

<!-- git stash でも同じです。 -->
$ git stash
Saved working directory and index state WIP on blog/2019-02-02: 8d5e7e6 rb -> ruby

上記のようにすると、退避されます。

$ git diff

stash を確認します。

$ git stash list
stash@{0}: WIP on blog/2019-02-02: 8d5e7e6 rb -> ruby

stash した変更ファイルを確認します。

$ git stash show
 src/pages/about.md | 2 ++
 1 file changed, 2 insertions(+)

stash した変更を適用する場合。

$ git stash pop
On branch blog/2019-02-02
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:   src/pages/about.md

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

	src/_posts/2019/02/02/

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (9dcbbfbfb3a3e29134614c679befcb226d1bdfe9)

名前をつけて stash する。

$ git stash save テスト
Saved working directory and index state On blog/2019-02-02: テスト

他の stash も追加した場合。

$ git stash list
stash@{0}: On blog/2019-02-02: テスト2回目
stash@{1}: On blog/2019-02-02: テスト

stash していた テスト (stash@{1}: On blog/2019-02-02: テスト) の変更を適用させたい場合。

$ git stash pop 1

テスト2回目 (stash@{0}: On blog/2019-02-02: テスト2回目) を削除したい場合。

$ git stash list
stash@{0}: On blog/2019-02-02: テスト2回目

$ git stash drop 0
Dropped refs/stash@{0} (4ce8fb30e02018a1fafac6d3feb9141358729bdc)

# git stash save -u

Untracked filesstash したい場合。

$ git stash save -u
Saved working directory and index state WIP on blog/2019-02-02: 8d5e7e6 rb -> ruby

Untracked files も名前をつけて stash する場合。

$ git stash save -u テスト
Saved working directory and index state On blog/2019-02-02: テスト

# その他

変更がない時に stash しようとすると

$ git stash save
No local changes to save

以下 3 つはすべて同じです。 どの stash か指定しない場合は、最新のものが適用されます。

$ git stash pop
$ git stash drop
$ git stash show
$ git stash pop 0
$ git stash drop 0
$ git stash show 0
$ git stash pop stash@{0}
$ git stash drop stash@{0}
$ git stash show stash@{0}

# 参考