git stash 使い方

現在のワークツリーを一時的に保存する

現在のブランチのワークツリーを一時的に保存するには stash を利用する。

git stash save

とするか、save を省略して

git stash

とする。

このとき、stash にメッセージをつけるには

git stash save "message"

とする。

stash に保存されている状態の一覧を見る

git stash list

で stash に保存されている状態のリストを見ることができる。

stash@{0}: WIP on master: 1c2aadc "COMMIT_MESSAGE"
stash@{1}: WIP on master: 1c2aadc "COMMIT_MESSAGE"

stash@{?} とブランチ、親コミットが表示される。

stash に保存されている状態に戻し、stash から削除する

一番最後に stash に保存した状態(stash@{0})を現在のブランチに適用するには

git stash pop

とする。このとき、適用した状態は stash から削除される。

stash@{0} 以外の stash に保存されている状態を適用するには、

git stash pop stash@{1}

のように指定して実行する。

stash に保存されている状態を適用するが、stash から削除はしない

git stash pop

とすると適用した変更は stash から削除される。 popの代わりに apply を使うと適用された変更は stash から削除されずに残る。

git stash apply
git stash apply stash@{1}

stash に保存されている状態を削除する

stash に保存されている状態を削除するには

git stash drop stash@{1}

などとする。

git stash drop

とすると最新のもの(stash@{0})が削除される。

stash に保存されている状態を全て削除する

stash に保存されている状態を全て削除するには clear を実行する。

git stash clear

stash の状態とその親コミットとの差を表示する

git stash show
git stash show stash@{1}

とすると stash の状態とその親コミットとの diffstat を表示する。

また、差分を表示したければ

git stash show -p

とする。

stash からブランチを作る

git stash branch new-branch

とすると最新の stash から新しいブランチ new-branch を作る。 stash を指定するにはブランチ名の後に記述する。

git stash branch new-branch stash@{1}

現在のワークツリーの一部を stash に保存する

単に

git stash

とすると HEAD との差分が stash に保存される。 この差分の一部を stash に保存するには「–patch」オプションをつける。

git stash --patch

インデックスに保存されている変更を除いて stash に保存する

git stash

とすると変更は stash に保存されてワークツリーは HEAD になる。

「-k」か「–keep-index」オプションをつけると、 インデックスに保存されてる変更を除いて stash に保存され、 インデックスはワークツリーにそのまま残る。

git stash -k

git stash pop でコンフリクトしたとき

git stash pop

でコンフリクトしたときは、stash から適用された状態は削除されない。 コンフリクトは手動で解決して、stash に保存されている状態は不要になったときに

git drop stash{0}

のようにして削除する。

stash に保存された状態を適用するときにインデックスに保存されていた変更はインデックスに戻す

git stash pop

とすると stash に保存されていた変更はインデックスに保存されていた変更であろうと すべてワークツリーに適用する。 「–index」オプションをつけると、インデックスに保存されていた変更は 現在のブランチのインデックスに保存される。

git stash pop --index

「–index」オプションは apply にも使える。

git stash apply --index

誤って削除した stash を復元する

誤って

git stash clear

とした場合に、stash に保存されていた状態を復元したいことがある。

git fsck でどこからもたどることができないコミットを探し、 その出力を編集して git log で探す。 シェルで

git fsck --unreachable | grep commit | cut -d\  -f3 | xargs git log --merges --no-walk --grep=WIP

とする。 この中で必要なコミットが見つかれば、その SHA-1 を

git cherry-pick -n -m1 <SHA-1>

としてインデックスに適用する。

stash を適用できないとき

git stash pop

とすると

error: Your local changes to the following files would be overwritten by merge:
        some_file
Please, commit your changes or stash them before you can merge.
Aborting
Index was not unstashed.

のようなエラーが出て適用できないことがある。 インデックスに保存されていない変更をインデックスに加えればよい (もちろん、きちんとコミットするか、stash してもよい)。たとえば、

git add -u

として更新をインデックスに加え

git stash pop

とする。

適用した stash の状態を取り消す

特別なコマンドはないのでパッチ形式で表示した結果をパイプで git apply -R に渡す。

git stash apply

で stash の最後の状態を適用したとする。このときに、この適用を取り消すには

git stash show -p | git apply -R

とすればよい。

参考

Tags of current page