退避したstashを消すコマンドは2つしかありません。1件だけ消すならgit stash drop、全部まとめて消すならgit stash clearです。迷うのはコマンドよりも、その前後のほうでしょう。どれを消してよいのか中身が分からない、番号を指定したら別のstashが消えた、popしたのに一覧から消えない、消してから必要だったと気づいた。この記事では、削除前の確認手順から、dropとclearの書き方、番号がずれる仕組み、PowerShellでの書き方の違い、誤って消したstashの復元までをコマンド付きで扱います。stash以外のGitコマンドを一通り見渡したい場合は用途別のGitコマンド一覧から入ると全体像をつかめます。
まとめ:git stashの削除はdropで1件・clearで全件、消す前に中身を確認
1件を消すならgit stash drop stash@{n}です。番号を省くと最新のstash@{0}が消えます。全件を消すならgit stash clearですが、こちらは確認なしで即座に全部消えます。
消す前にgit stash listで番号を、git stash show -pで中身を確かめてください。dropすると後ろの番号が1つずつ詰まるため、複数を消すときは大きい番号から順に消すのが安全です。
popがコンフリクトで止まった場合、そのstashは一覧に残ります。解決後に自分でdropするのが公式ドキュメントの指示です。誤って消したstashは通常の手段では戻せませんが、gcで掃除される前ならgit fsckで探し出して復元できる可能性があります。
git stash listとshow -pで削除前に退避の中身と番号を確かめる手順
削除の事故は、ほぼすべて「消す対象を取り違えた」ことから起きます。コマンドを打つ前の確認を先に固めておきましょう。
git stash listで番号・作成元ブランチ・メッセージを読む
git-stashの公式ドキュメントによれば、git stash listは各エントリを名前、作成時のブランチ名、元にしたコミットの短い説明とともに表示します。stash@{0}が最新で、stash@{1}がその1つ前です。
git stash list
git stash list --date=relative
2行目のように日付を付けると、いつ退避したものかが見えます。「WIP on main」のような自動メッセージばかり並んでいる場合は、判別に使える唯一の手がかりは、作成日時とブランチ名です。この先の章で触れるとおり、退避時に-mでメッセージを付けておくと、ここでの判別が格段に楽になります。
show -pと–include-untrackedによる退避内容の差分確認
番号が分かったら中身を見ます。git stash showは既定では変更ファイルの一覧と行数だけを出すので、差分そのものを見るには-pを付けます。
git stash show -p stash@{1}
git stash show --include-untracked stash@{1}
2行目が見落とされがちです。git stash push -uで未追跡ファイルごと退避したstashは、通常のshowでは未追跡ファイルが表示されません。公式ドキュメントは、showに--include-untrackedを付けると未追跡ファイルも差分に含めて表示すると説明しています。新規作成したファイルだけを退避していたstashを「中身が空だから」と消してしまう事故は、この1行で防げます。
git stash dropで特定の1件を削除する書き方と番号がずれる仕組み
1件を消すコマンドは単純ですが、番号の扱いとシェルの違いで2つの落とし穴があります。
dropで番号を指定する書き方と省略時に消えるstash@{0}
公式ドキュメントはdropを「stashエントリの一覧から1件を取り除く」と定義し、<stash>を省略した場合は最新、つまりstash@{0}が対象になると明記しています。
git stash drop
git stash drop stash@{2}
git stash drop 2
1行目は最新の1件を、2行目は3番目に新しい1件を消します。3行目は2行目と同じ意味です。同じドキュメントに「整数の<n>はstash@{<n>}と等価」とあり、番号だけで指定できます。削除に成功すると「Dropped」で始まる行が出て、末尾の括弧内に消したstashのハッシュ値が表示されます。このハッシュは後で復元に使えるので、すぐに画面を閉じないでください。
PowerShellでstash@{1}が通らないときのクォートと整数指定
WindowsのPowerShellでは、引用符のない波括弧{…}がシェル側の構文として解釈されるため、git stash drop stash@{1}がそのままでは意図どおりに渡りません。引数を引用符で囲むか、整数だけで指定します。
git stash drop 'stash@{1}'
git stash drop 1
Git BashやmacOS・Linuxのbash、zshではクォートなしで通ります。チームの手順書にstashの番号指定を書くなら、シェルを問わず動く整数指定に揃えておくと、環境ごとの書き分けが要らなくなります。
複数のstashを削除するときに番号ずれを防ぐ大きい番号からの削除
stashはrefs/stashのreflogとして並んでいます。途中の1件をdropしたときの変化は、それより古いエントリの番号が1つずつ繰り上がることです。stash@{1}を消した直後、もとのstash@{2}はstash@{1}になっています。
このため「1番と3番を消したい」ときに1番から消すと、次の3番の指定は本来の4番を指してしまいます。大きい番号から消せば、まだ消していない側の番号は動きません。
git stash drop 3
git stash drop 1
git stash list
古いstashをまとめて間引くなら、bash系シェルでは次のように番号を降順で回します。下の例はstash@{2}以降を残らず消し、新しい2件だけを残す書き方です。
n=$(git stash list | wc -l)
for i in $(seq $((n-1)) -1 2); do git stash drop "stash@{$i}"; done
git stash list
git stash clearで全件を削除する前に退避を書き出しておく方法
clearは確認プロンプトを出しません。打った時点で一覧は空になります。
clearの挙動と「復元できない可能性がある」という公式の注意
公式ドキュメントのclearの説明は短く、「すべてのstashエントリを削除する」の直後に注意書きが続きます。削除されたエントリは刈り取り(pruning)の対象になり、復元できなくなる可能性がある、というものです。
git stash list | wc -l
git stash clear
git stash list
1行目で件数を見てから2行目を打つ、という順番だけは守ってください。件数が想定より多いなら、その中に消してはいけない退避が混ざっていると疑うべきです。
Git 2.51のgit stash exportでclear前に退避をrefへ書き出す
Git 2.51.0で、stashを書き出して取り込むサブコマンドが加わりました。Git 2.51.0のリリースノートには、stashエントリの交換形式を定義し、import/exportのサブコマンドを追加したと記載されています。
git --version
git stash export --to-ref refs/stash-backup
git stash clear
git stash import refs/stash-backup
2行目で全stashを1本のコミット列としてrefs/stash-backupに保存し、3行目で一覧を空にします。必要になったときに一覧へ戻すための操作が、4行目のコマンドです。公式ドキュメントはexportの結果を通常のfetchとpushで転送できると説明しており、別マシンへの退避の引っ越しにも使えます。1行目で2.51より前と分かった場合は、git stash show -p stash@{n} > stash-n.patchのように差分をファイルへ書き出しておくのが代替手段です。
popがコンフリクトで止まったときにstashが残る理由と後片付け
「popしたのに一覧から消えない」という相談の大半は、不具合ではなく仕様どおりの動きです。
popの適用成功時だけstashを削除し、競合時には残す公式の仕様
popは、適用とdropを1回で行うコマンドです。ただし公式ドキュメントには、適用がコンフリクトで失敗した場合はstashを一覧から取り除かないと書かれています。手でコンフリクトを解決し、そのあと自分でgit stash dropを呼ぶよう指示されています。
git stash pop
git status
git add <解決したファイル>
git stash drop
退避が残るのは安全側に倒した設計です。コンフリクトを解決し損ねても、元の退避から何度でもやり直せます。解決の進め方そのものはコンフリクトが起きる仕組みと解消手順で詳しく扱っています。
applyとbranchで退避内容を適用してから削除するまでの流れ
適用が確実に通ったと目で確かめてから消したいなら、popではなくapplyを使います。applyはpopと同じ適用をしますが、一覧からは消しません。
git stash apply stash@{0}
git diff
git stash drop stash@{0}
退避元のコミットから離れすぎて適用がうまくいかない場合は、git stash branch <新ブランチ名> stash@{n}が使えます。stashを作った時点のコミットから新しいブランチを切って適用し、成功すればそのstashを自動でdropします。ブランチの仕組みを押さえておくと、この動きの意味が読みやすくなるはずです。
誤って削除したstashをgit fsckとハッシュ値から復元する手順
公式ドキュメントは、dropやclearで誤って消したstashは通常の安全機構では戻せないと明言しています。ただし、まだリポジトリの中にオブジェクトが残っていれば拾い上げられます。
dropの表示ハッシュかgit fsck –unreachableで候補を探す
dropした直後なら、画面に出たDropped … (ハッシュ)の値がそのまま使えます。ターミナルを閉じてしまった、あるいはclearで消した場合に探す対象は、到達不能なコミットです。git-fsckの公式ドキュメントは--unreachableを「存在するが、どの参照からも到達できないオブジェクトを表示する」と定義しています。git-stashのドキュメントには、これを使った次の用例が載っています。
git fsck --unreachable |
grep commit | cut -d\ -f3 |
xargs git log --merges --no-walk --grep=WIP
stashの実体は、作業ツリーの状態を記録したマージ形式のコミットです。そのため--mergesで絞り込み、自動メッセージに含まれる「WIP」で検索しています。-mで独自のメッセージを付けて退避していた場合は、--grepの語をそのメッセージに合わせてください。
git stash applyとstoreで見つけたハッシュを一覧へ戻す
候補のハッシュが見つかったら、中身を確かめてから戻します。公式ドキュメントによれば、applyにはstash pushなどで作られたコミットに見えるものなら任意のコミットを渡せます。stashを一覧に戻したい場合に使うコマンドはstoreです。
git stash show -p <ハッシュ>
git stash apply <ハッシュ>
git stash store -m "restored" <ハッシュ>
2行目は作業ツリーへ直接適用し、3行目は適用せずにstash一覧へ登録し直します。まず3行目で一覧に戻しておけば、あとで落ち着いて適用できます。
gcの既定2週間と到達不能オブジェクトの刈り取りによる復元期限の目安
復元には期限があります。到達不能になったオブジェクトは、gcで刈り取られるまでしか残りません。git-gcの公式ドキュメントによれば、--pruneの既定は2週間前で、設定値gc.pruneExpireで変えられます。gcは手で打たなくても、緩いオブジェクトがgc.autoの既定6700個を超えると一部のコマンドの後に自動で走ります。
したがって「消してから2週間以内なら望みがある」というのが実務上の目安です。逆に言えば、それより前に消したstashはfsckでも見つからないと考えておくべきでしょう。復元の手順を覚えるより、消す前の確認と書き出しを習慣にするほうが確実です。
stashをためこまない運用:残す基準と古い退避を整理する判断
削除で迷うのは、stashがたまっているからです。受託開発の現場で効くのは、削除の手順よりも、たまらない使い方を先に決めておくことです。
stashは当日中に戻す一時退避、残すならメッセージを付ける
線引きは単純にします。stashは当日中に戻す一時退避に限り、翌日以降に持ち越す作業はブランチにWIPコミットとして残す。stashはpushされないため、手元のマシンが壊れれば一緒に消えます。ブランチにコミットしておけばリモートにも置けますし、番号の取り違えも起きません。
どうしても数日残すstashには、git stash push -m "ログイン画面のバリデーション途中"のように用件が分かるメッセージを付けます。並行作業が日常的に発生するなら、stashで切り替えるよりGit Worktreeで作業ディレクトリを分ける方法のほうが、退避そのものが不要になります。
dropとclearを見送るべき場面と、消してよい場面の判断
消してよいのは、show -pで中身を確かめ、同じ変更がすでにコミット済みと分かったstashです。applyで戻して作業を終えたstashも、そのままdropして構いません。
見送るべき場面もはっきりしています。中身を見ていない、未追跡ファイルを含むか分からない、作成元のブランチがもう存在しない。この3つのどれかに当てはまるstashは消さずに、git stash branchでブランチへ移してから判断してください。clearは、exportで書き出したあとか、全件の中身を確かめたあとにだけ打つものと決めておけば、取り返しのつかない削除はほぼ起きません。TUIで一覧と差分を見比べながら整理したい場合は、Lazygitの使い方のstashパネルも選択肢になります。
引き渡し後のリポジトリでは、こうした退避やブランチの扱いが人によってばらばらになりやすく、手順が口伝のまま残ることが少なくありません。Git運用のルールづくりから内製チームが自走するまでの伴走は、保守運用・内製化支援で承っています。
よくある質問
stashの削除について、検索でよく見かける質問に答えます。
git stash dropで番号を指定しないと何が消えますか?
番号指定を省略したときの削除対象は、最新のstash@{0}です。公式ドキュメントに、<stash>を省略した場合は最新のstashが対象になると明記されています。古い退避を消したいのに番号を付け忘れると、直前に退避した作業が消えてしまいます。消す前にgit stash listで番号を確かめ、必ず番号付きで指定する習慣にしておくと安全です。
git stash popしたのにstashが一覧から消えないのはなぜですか?
適用がコンフリクトで失敗したためです。公式ドキュメントでは、popはコンフリクトが起きた場合にstashを一覧から取り除かず、手で解決したあとにgit stash dropを自分で呼ぶよう指示しています。git statusでコンフリクトを解決し、変更が正しく入ったことを確かめてからdropしてください。
git stash clearで消したstashは元に戻せますか?
gcで刈り取られる前なら戻せる可能性があります。git fsck --unreachableで到達不能なコミットを洗い出し、git log --merges --grep=WIPで絞り込む用例が公式ドキュメントに載っています。見つけたハッシュを一覧に戻すためのコマンドはgit stash storeです。gcの--pruneの既定は2週間前なので、それを過ぎると見つからない可能性が高くなります。
PowerShellでstash@{1}のdropがエラーになるのはなぜですか?
PowerShellが引用符のない波括弧{…}をシェル側の構文として扱い、Gitへ文字列のまま渡らないためです。git stash drop 'stash@{1}'のように引用符で囲むか、git stash drop 1のように整数だけで指定してください。公式ドキュメントにも、整数の<n>はstash@{<n>}と等価とあります。
特定のファイルだけをstashから削除できますか?
dropとclearはエントリ単位の削除なので、1つのstashから一部のファイルだけを取り除く操作はありません。必要なファイルだけを残したい場合は、git stash branchやgit stash applyでいったん作業ツリーへ戻し、不要なファイルを捨ててからgit stash push -- <残すファイル>で退避し直します。元のstashは、新しい退避をshow -pで確かめてからdropしてください。
関連記事
- Gitコマンド一覧|用途別早見表とよく使う基本コマンドの使い方を解説:stashを含むGitコマンド全体を用途別に見渡せます。
- git mergeの取り消し|abort・reset・revert -mの使い分け:マージ前にstashで手を空にしておく理由と、マージそのものの戻し方を扱っています。
- コンフリクトとは?Gitで変更が衝突する仕組みと解消手順・予防設計を実装視点で解説:stash popがコンフリクトで止まったときの解決手順です。
- Git Worktree(ワークツリー)とは|使い方・削除(remove/prune)とsubmodule併用の注意点:stashを使わずに並行作業を分ける方法です。
- Lazygit入門|Windows・Mac・Linuxのインストールと使い方・ショートカットを徹底解説:stashの一覧と差分をターミナル上のUIで確認しながら整理できます。