git stashコマンドで編集中の作業を一時的に退避&戻す方法|戻す

git_stashコマンド NEWS
git_stashコマンド
この記事は約18分で読めます。

はじめに

ワークツリーで編集中のファイルや、ステージに上げたファイルを一時退避させたい場合git stashコマンドを使って、作業内容を一時的に退避させましょう。

例えば、作業途中で別ブランチに切り替える必要が発生した場合、現在の作業内容をスタッシュに退避させておけば安心です。

もちろん、退避した作業を元に戻す方法も記載しています。

失念防止用の備忘録として、残しておきたいと思います。

訓練兵A
訓練兵A

教官!例えば、あるブランチでファイルを修正しているときに、急ぎで別ブランチの作業をしなくちゃいけなくなった場合は、どうすればいいんですか?

鬼軍曹
鬼軍曹

そんなときは、今回のテーマでもあるgit stashコマンドを使って、作業を一時退避してあげればいいのよ。

訓練兵A
訓練兵A

一時退避ですか?それって、後でちゃんと元に戻すことはできるんですか?

鬼軍曹
鬼軍曹

できるわよ。わざわざ、編集中のファイルをコミットしなくても、git stashで一時退避させておけば、後で簡単に元に戻すことができるの。

訓練兵A
訓練兵A

意外と便利そうなコマンドですね。

鬼軍曹
鬼軍曹

結構便利よ。それでは、一緒にgit stashコマンドについて、みていきましょう!

基本構文

git stashコマンドの基本的な構文は、以下になります。

# 基本構文
$ git stash

# もしくは、
$ git stash save
※「save」は省略可能です。

git stashコマンドを実行することで、ワークツリーで編集中のファイルやステージの未コミットファイルはスタッシュに一時退避されます。

具体的な使用方法については、次の「オプション」の説明の後に記載していますので、ご参考にしてください。

オプション

git stashコマンドのオプションは、以下になります。

訓練兵A
訓練兵A

オプションって、結構あるんだな~。

オプション説明
save省略可能。<message>を使用する場合は必須。
save <message>スタッシュにメッセージを指定することが可能。
例)$ git stash save “ここにメッセージを入れます”
-p (–patch)変更内容を確認しながらスタッシュに保存。
-k (–keep-index)ステージの内容もスタッシュに保存。
–no-keep-indexステージの内容をスタッシュに保存しない。
-u (–include-untracked)バージョン管理外のファイルもスタッシュに保存。
-a (–all)バージョン管理外のファイルと.gitignoreに指定しているファイルもスタッシュに保存。
apply一時退避した(最新の)作業内容をスタッシュから復元する(stash@{0})。ワークツリーのみ復元される。ステージの変更も復元させるには、「–index」オプションをつける。
listスタッシュに保存されている内容を一覧表示。
drop一時退避した(最新の)作業内容を削除する(stash@{0})。特定のスタッシュを削除したい場合は、「$ git stash drop stash@{数字}」を実行する。
clear全てのスタッシュを削除。
鬼軍曹
鬼軍曹

必要に応じて使えばいいのよ。

【一時退避】編集中の作業をgit stashで一時退避させる

ワークツリーで編集中のファイルや、ステージに上げたファイル(未コミット)をgit stashコマンドでスタッシュに一時退避させる方法を見ていきます。

ワークツリーやステージの作業を一時退避させる方法($ git stash)

冒頭でも少しご紹介しましたが、編集中の作業内容(ワークツリーやステージ)をgit stashコマンドを使って一時退避させてみましょう。

以下の説明では、ワークツリーで編集中のファイルをスタッシュに一時退避させていますが、ステージに未コミットファイルがある場合も同様です。

まずは、index.htmlを作成しコミットまで行います。

# ワークツリーでindex.htmlを作成(atom) + $git add + $git commit
$ touch index.html
$ atom index.html
$ cat index.html
<p>index.htmlを作成</p>
$ 

# git add でステージに上げます。
$ git add index.html

# コミットします
$ git commit

因みに、一度もコミットしていないファイルをスタッシュしようとすると、次のようなエラーが表示されます。

# 一度もコミットしていないファイルをスタッシュしようとすると、エラーが表示されます。
$ git stash
You do not have the initial commit yet

続いて、index.htmlを以下の通り修正し、git stashコマンドでスタッシュに格納しましょう。

index.htmlに「<p>index.htmlを修正しました。</p>」を追記します。

# index.htmlを修正
$ atom index.html
$ cat index.html
<p>index.htmlを作成</p>
<p>index.htmlを修正しました。</p>

$

$ git status コマンドで現在の状態を確認

一旦、git statusコマンドで現在の状態を確認します。

訓練兵A
訓練兵A

現在の状態を確認するんですね。ふむふむ。

# git status で現在の状態を確認
$ git status
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:   index.html

no changes added to commit (use "git add" and/or "git commit -a")
$

「git add しなさいよ」と言われていますね。

ここでは、git add せずにワークツリーで編集中にスタッシュに一時退避させたいと思います。

もし、git statusコマンドについて復習したければ、こちらもご参考にしてください。

訓練兵A
訓練兵A

git statusコマンドについて、もう一度復習しておこうかな。

それでは、git stashコマンドで作業をスタッシュに一時退避させます。

# スタッシュに一時退避
$ git stash
Saved working directory and index state WIP on master: adbb779 最初のコミットです。

スタッシュに一時退避されましたね。

再度、git statusコマンドで現在の状態を確認します。

# 再度、git status で状態を確認
$ git status
On branch master
nothing to commit, working tree clean

編集中だった作業内容がスタッシュに一時退避され、編集前の状態になったことがわかります。

念のため、index.htmlの中身も確認してみましょう。

# index.html の中身を確認してみます。
$ cat index.html
<p>index.htmlを作成</p>
訓練兵A
訓練兵A

お~、編集前の状態に戻っていますね。

続いて、git stash listコマンドで、現在のスタッシュの状態も確認してみましょう。

# git stash list で、スタッシュの状態を確認
$ git stash list
stash@{0}: WIP on master: adbb779 最初のコミットです。

「stash@{0}」と表示されているのが最新のスタッシュです。

今後、スタッシュが増えていくと、「stash@{1}」は1つ前のスタッシュ、「stash@{2}」は2つ前のスタッシュであることを表します。

【状態確認】stashの状態を確認する方法($ git stash list)

git stashコマンドで編集中の作業をスタッシュに一時退避させましたが、現在のスタッシュの状態を確認するには、git stash listコマンドを実行します。

鬼軍曹
鬼軍曹

git stash list コマンドで、スタッシュの状態を確認するわよ。

# git stash list でスタッシュの状態を確認
$ git stash list
stash@{0}: WIP on master: adbb779 最初のコミットです。

「stash@{0}」と表示されているのが最新のスタッシュです。

今後、スタッシュが増えていくと、「stash@{1}」は1つ前のスタッシュ、「stash@{2}」は2つ前のスタッシュであることを表します。

因みに、ワークツリーやステージに変化がない状態で、再度git stashコマンドを実行すると、次のように表示されます。

# ワークツリーやステージに変化がない状態での$git stash実行時
$ git stash
No local changes to save

編集作業を行い、git stashコマンドを実行するとスタッシュの履歴が変わりますので、今どのような状態になっているのかを知りたいときに、便利なコマンドですね。

【戻す方法】一時退避した作業内容を復元する方法($ git stash apply)

git stashコマンドで一時退避させたファイルを復元、つまり戻す方法について見ていきます。

訓練兵A
訓練兵A

おっ!ここからファイルを戻す方法について、見ていくんですね。楽しみです。

ワークツリーで編集中だった作業内容を復元(戻す)方法($ git stash apply)

ワークツリーで編集中だった作業内容のみを元に戻す方法は、git stash applyコマンドを実行します。

【ご注意】ワークツリーで編集中だったファイルだけでなく、ステージに上げたファイルも元に戻す場合は、次に挙げる「$ git stash apply –index 」コマンドを実行する必要があります。

まずは、git statusコマンドおよび、git stash listコマンドで現在の状態を確認します。

# $git status で現在の状態を確認
$ git status
On branch master
nothing to commit, working tree clean
※ふむ。差分はなさそうですね。

# $git stash list で現在のスタッシュの状態を確認
$ git stash list
stash@{0}: WIP on master: adbb779 最初のコミットです。
※ふむ。スタッシュには1個だけしかありませんね。

でわ、スタッシュ(stash@{0})を復元したいと思います。

# $git stash apply でワークツリーの作業内容を復元
$ git stash apply
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:   index.html

no changes added to commit (use "git add" and/or "git commit -a")
$

index.htmlの修正箇所が、復元されたかどうか見てみましょう。

# index.html の修正分が復元されたかどうかを確認
$ cat index.html
<p>index.htmlを作成</p>
<p>index.htmlを修正しました。</p>

お~、復元されましたね(最終行)。

これで作業の続きを行い、ステージにファイルを上げてコミットする流れですね。

今回はワークツリーのみの復元でしたが、ステージ分も復元したい場合は、次に説明している「$ git stash apply –index 」コマンドを実行しましょう。

ステージに上げたファイルも復元する方法($ git stash apply –index)

git stash applyコマンドを実行しただけでは、ワークツリーで編集中だった作業しか復元できません。

ステージに上げたファイルも含めて復元したい場合は–indexを追記した、「$ git stash apply –index 」コマンドを実行する必要があります。

試してみましょう。

ここでは、ワークツリーには修正したindex.htmlがあり、ステージにはhome.html(未コミット)があるとします。

$ ls
home.html  index.html

# ワークツリーには編集したindex.htmlがあり、ステージにはhome.htmlがいる状況
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   home.html

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:   index.html

git stashコマンドを実行し、作業内容をスタッシュに退避させます。

# 現在のスタッシュの状態を確認
$ git stash list
stash@{0}: WIP on master: f5e7894 2回目のコミット
stash@{1}: WIP on master: adbb779 最初のコミットです。

# 現在の作業内容をスタッシュに退避
$ git stash
Saved working directory and index state WIP on master: 1f8aca9 home.htmlをコミット

# $git status で現状を確認
$ git status
On branch master
nothing to commit, working tree clean

# $git stash list でスタッシュの現状を確認
$ git stash list
stash@{0}: WIP on master: 1f8aca9 home.htmlをコミット
stash@{1}: WIP on master: f5e7894 2回目のコミット
stash@{2}: WIP on master: adbb779 最初のコミットです。

「stash@{0}」に今回の作業内容が退避されましたね。

続いて、「stash@{0}」「$ git stash apply –index 」コマンドで復元してみましょう。

# ステージを含めて復元
$ git stash apply --index
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   home.html

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:   index.html

ステージにはコミット前のhome.htmlが、ワークツリーには編集中のindex.htmlが復元されました。

因みに、git stash applyコマンドを実行した後もスタッシュには残っているので、「–indexをつけ忘れてしまった!」という場合も安心ですね。

ただ、マージが発生した場合は、少し作業が必要になりますね。

【削除方法】一時退避した作業内容を削除する方法($ git stash drop)

最新のスタッシュを削除する方法($ git stash drop)

スタッシュに退避させた最新の作業内容を削除するには、「$ git stash drop 」コマンドを実行します。

# 現在のスタッシュの状態を確認
$ git stash list
stash@{0}: WIP on master: 1f8aca9 home.htmlをコミット
stash@{1}: WIP on master: f5e7894 2回目のコミット
stash@{2}: WIP on master: adbb779 最初のコミットです。

# git stash drop で最新のスタッシュを削除
$ git stash drop
Dropped refs/stash@{0} (1eaa87926e23b496f16ffc74cd7361cdba293f42)

# 再度、スタッシュの状態を確認
$ git stash list
stash@{0}: WIP on master: f5e7894 2回目のコミット
stash@{1}: WIP on master: adbb779 最初のコミットです。
※ふむ。最新のスタッシュが消えて2行になりましたね。

特定のスタッシュを削除する方法($ git stash drop [スタッシュ名])

特定のスタッシュを削除するには、「$ git stash drop [スタッシュ名] 」コマンドを実行します。

# git stash list で現在のスタッシュの状態を確認
$ git stash list
stash@{0}: WIP on master: f5e7894 2回目のコミット
stash@{1}: WIP on master: adbb779 最初のコミットです。

# 「stash@{1}」を削除してみます。 
$ git stash drop stash@{1}
Dropped stash@{1} (48fc0765133a505630ccae998bb9afc72578326f)

# 再度、スタッシュの状態を確認
$ git stash list
stash@{0}: WIP on master: f5e7894 2回目のコミット

無事、指定したスタッシュが削除されましたね。

これで、複数のスタッシュがあっても、不要なスタッシュを削除することができます。

全スタッシュを削除する方法($ git stash clear)

スタッシュに一時退避されている全てのスタッシュを削除するには、「$ git stash clear 」コマンドを実行します。

現在のスタッシュには、2つのスタッシュがあるとします。

# git stash list で現在のスタッシュの状態を確認
$ git stash list
stash@{0}: WIP on master: 1f8aca9 home.htmlをコミット
stash@{1}: WIP on master: f5e7894 2回目のコミット

# git stash clear で全てのスタッシュを削除
$ git stash clear
$

# git stash list で再度、スタッシュの状態を確認
$ git stash list
$

綺麗にお掃除ができました。

スタッシュにメッセージを指定する方法

作業内容をスタッシュに退避する際、メッセージを指定することができます。

【ご注意】オプションの「save」と一緒に使用しないと、エラーで弾かれます。

# スタッシュにメッセージを指定
$ git stash save "index.htmlを一部修正"
Saved working directory and index state On master: index.htmlを一部修正

# スタッシュの状態を確認
$ git stash list
stash@{0}: On master: index.htmlを一部修正

以下、失敗例です。

# 失敗例(その壱)
$ git stash "test123"
fatal: unknown subcommand: test123

# 失敗例(その弐)
$ git stash <index.htmlを一部修正>
bash: syntax error near unexpected token `newline'

# 失敗例(その参)
$ git stash "index.htmlを一部修正"
fatal: unknown subcommand: index.htmlを一部修正

スタッシュにメッセージを指定したい場合は、「save」オプションと一緒に使いましょう。

まとめ

git stashコマンドは、作業内容をスタッシュに退避させる単純なコマンドではありますが、いろいろなオプションもあり、細かい部分も多いかと思います。

今回のgit stashコマンド以外にも、Gitには以下のように沢山のコマンドがありますので、こちらもご参考にしてください。

訓練兵A
訓練兵A

git addコマンドについても、復習しておこうかな。

鬼軍曹
鬼軍曹

git branchコマンドについても、よかったら復習してね。

コメント

タイトルとURLをコピーしました