作業中のファイルを一時中断して、退避する「stash」についてまとめたのでメモ。
stashコマンドを使うと、中途半端な作業の途中でコミットする必要がありません。
退避させたいファイルを、一時的に違う場所によけておくイメージです。
基本のコマンド
今回スタッシュすることで、図のような状態になると仮定します。作業ブランチはdevelopです。
index.htmlがワーキングディレクトリに、post.htmlがステージングエリアにある状態です。
作業ファイルを全てstashする
上記の作業状態をstatusコマンドで確認すると次のようになります。
$ git status
On branch develop
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: post.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 [save "<メッセージ>"]
ワーキングディレクトリとステージングエリアにあるファイルがスタッシュに退避されます。
コメントをつけて保存する場合、saveオプションで”stash add no03”のようなコメントをつけてスタッシュします。メッセージをつけておくと、後で管理がしやすいです。
$ git stash save "stash add no03" #コメントをつけてstashする
Saved working directory and index state On develop: stash add no03
これでファイルが退避できました。
未追跡のファイルをstashする
尚、以下のようにgitで管理していないファイル(untracked file)は、通常スタッシュされません。
$ git status
On branch develop
Untracked files:
(use "git add <file>..." to include in what will be committed)
test.txt
未追跡のファイルも退避させたい場合は、stashコマンドに次のオプションを指定します。
$ git stash -u
コメントを記載する場合、次のようにコマンドを使用します。
$ git stash save -u "untrackファイルを退避"
stashしたリストを確認する
スタッシュしたリストを確認するには次のコマンドを使用します。
$ git stash list
このようなリストが表示されます。
stash@{0}はスタッシュの管理番号になります。
今回、コメントにスタッシュした順番をno01〜03で記載しました。
リストを確認すると、新しくスタッシュしたものが上に積み上がっています。
そのため、古いスタッシュほど番号が古くなります。
stashしたファイルを元に戻す
スタッシュしたファイルを元に戻すには次のコマンドを使用します。
$ git stash apply [stash @{<i>}]
オプションがない場合、最新のスタッシュのファイルがワーキングディレクトリに戻ります。
特定のスタッシュを戻したい場合、オプションでスタッシュの管理番号を指定します。
ここでのポイントは2つです。
- 全てのファイルはワーキングディレクトリに移動する。ステージングエリアにあったファイルも同様。
- 戻したスタッシュは削除されることなく残る。
applyでワーキングディレクトリにファイルを戻してもスタッシュのリストは削除されません。
削除するには別途コマンドを実行する必要があります。
stashを削除する
スタッシュを削除するには、次のコマンドを使用します。
特定のスタッシュを削除したい場合、オプションでスタッシュの管理番号を指定します。
$ git stash drop [stash @{<i>}]
stashしたファイルをワーキングディレクトリに戻し、stashも削除する
ファイルを戻すapplyとスタッシュを削除するdropを同時に行うには、次のコマンドを使用します。
$ git stash pop [stash @{<i>}]
stashの情報を確認する
スタッシュの詳細を確認するには、次のコマンドを使用します。
$ git stash show [stash @{<i>}]
stashのコンフリクトについて
ファイルをスタッシュからワーキングディレクトリに戻す際、ワーキングディレクトリに同じファイルが存在し、さらにファイルの内容を変更している場合、次のようなエラーになります。
$ git stash apply stash@{2}
error: Your local changes to the following files would be overwritten by merge:
index.html
Please commit your changes or stash them before you merge.
Aborting
どうやら、ワーキングディレクトリにある該当ファイルが上書きされるので、コミットするなり隠すなりしないとファイルを戻せないようです。
では、該当ファイルをステージングエリアに移動してから、stash applyしてみます。
$ git stash apply stash@{2}
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
今度は、コンフリクトが発生します、、。コンフリクトは通常通り対応すればOKです。
スタッシュを戻す際、ワーキングディレクトリはクリーンな状態にしておくのがベストのようです。
まとめ
スタッシュは、作業中のファイルを退避することができる便利な機能です。
ブランチを間違えて作業していた時、いざブランチを切り替えようとしたらエラーが発生して切り替えができない!なんて時も重宝します。