【完全ガイド】git stash の使い方|push/pop/apply の違い・untracked/partial stash・トラブル対応まで徹底解説

【完全ガイド】git stash の使い方|push/pop/apply の違い・untracked/partial stash・トラブル対応まで徹底解説

作業中に「あ、緊急で別ブランチの修正が必要」「pull したいけど未commitの変更がある」…そんな時に頼れる Git の便利機能が stash:

# 作業中の変更を一時退避
git stash

# ブランチ切り替え、pull、緊急対応など自由に

# 元の作業に戻る
git stash pop

git の一時的な避難場所として、日々多用される機能。しかし、実際に使い始めると:

  • git stash popgit stash apply どっちを使う?
  • 新規ファイル(untracked)が stash されない!
  • 「WIP on branch」だらけで、どの stash か分からない
  • pop で conflict が発生した時どうする?
  • 一部の変更だけ stash したい
  • 消してしまった stash を復旧できる?
  • stash した内容を別ブランチで開いていい?
  • git stash save は使ってはいけない?
  • チームで stash を共有したい

など、意外と知らない機能や落とし穴が多くあります。

pop vs apply の違いを知らないと重要な変更を失うリスクも。untracked ファイルの罠に何度も引っかかった経験のある方も多いはず。

本記事では、git stash完全な使い方を、リファレンスとして実用的に整理します。基本コマンド、push vs save の非推奨事情、pop vs apply の決定的違い、untracked / ignored ファイルの扱い、部分的 stash(-p)、stash branch による安全な復旧、stash list/show/drop/clear、conflict on pop 対処、削除した stash の復旧、実践パターン、トラブル対応、FAQまで完全網羅。この1本で stash を安全かつ自在に使いこなせるようになります。


目次

結論:これだけ覚えれば OK

時間がない方向けに、最重要ポイントを先に示します。

頻出コマンド Top 10

# ① 基本の stash(メッセージ推奨)
git stash push -m "WIP: user auth"

# ② untracked ファイルも含める(重要!)
git stash push -u -m "WIP: 新ファイル含む"

# ③ 一覧
git stash list

# ④ 適用して消す
git stash pop

# ⑤ 適用して残す(安全)
git stash apply

# ⑥ 特定の stash を適用
git stash apply stash@{2}

# ⑦ 中身を確認
git stash show -p stash@{0}

# ⑧ 削除
git stash drop stash@{0}

# ⑨ 全部削除
git stash clear

# ⑩ 別ブランチで展開
git stash branch new-feature stash@{0}

【最重要】pop vs apply の違い

コマンド動作用途
git stash pop適用してstash 削除通常の使い方
git stash apply適用してstash 保持不安な時、複数ブランチに適用

不安なら apply → 動作確認後に drop が安全。

【最重要】untracked ファイル

デフォルトでは 新規ファイル(untracked)は stash されない:

# ❌ 新ファイルを忘れる
git stash

# ✅ -u で新ファイルも含める
git stash -u

詳細は以下で解説します。


まず理解する:stash とは何か

stash の仕組み

stash は「作業ディレクトリの変更を一時的に**スタック(LIFO)**に退避する」機能:

[作業中の変更]
    ↓ git stash
[退避スタック(stash@{0}, stash@{1}, ...)]
    ↓ git stash pop
[作業ディレクトリに戻る]

使うタイミング

  1. 緊急で別ブランチに切り替える必要が出た
  2. git pull したいが未commit の変更がある
  3. 実験的な変更を一時保存しておく
  4. 半端な状態でテストを走らせたい
  5. 一時的にキレイな状態にしたい(CI/CD の再現テスト等)

stash はローカル限定

⚠️ stash はローカル環境のみに存在、リモートに push されない:

  • チームメンバーには見えない
  • 別のマシンからアクセス不可
  • バックアップにならない

「一時退避」以上に使わないこと。長期保存が必要なら別ブランチを作る

stash の実態

Git の内部では、stash も実はコミットの一種:

git log --oneline refs/stash
# abc1234 WIP on main: 5002d47 our new homepage

refs/stash という特殊参照に紐付けられ、古いものは reflog に。


基本の stash

git stash(デフォルト)

git stash

以下と同等:

git stash push

出力:

Saved working directory and index state WIP on main: 5002d47 our new homepage

メッセージ付き(推奨)

git stash push -m "WIP: user auth logic"

必ずメッセージを付ける習慣を。「WIP on main」ばかりだと後で見分けられない:

stash@{0}: On main: WIP: user auth logic
stash@{1}: WIP on main: abc1234 previous commit
stash@{2}: WIP on main: def5678 another commit

一目で判別できる。

stash push vs stash save(非推奨)

過去には git stash save "message" が主流でしたが、現在は非推奨:

# ❌ 非推奨(Git 2.16 以降)
git stash save "message"

# ✅ 推奨
git stash push -m "message"

理由:

  • save は限定的な機能
  • push はより柔軟(pathspec 対応など)
  • 公式ドキュメントも push を推奨

新規スクリプトでは push を使うこと


untracked / ignored ファイル

デフォルトの落とし穴

# 状況
git status
# On branch main
# Changes to be committed:
#   modified: index.html
# Untracked files:
#   script.js       ← 新ファイル

git stash
# Saved working directory and index state WIP on main: xxx

git status
# On branch main
# Untracked files:
#   script.js       ← ⚠️ 残っている!

modified は退避されるが、新規ファイルは残る。多くの人がハマる罠。

-u(–include-untracked)

git stash -u
# または
git stash --include-untracked
# または
git stash push -u -m "含めた"

これで新規ファイルも含まれる

-a(–all)

git stash -a

Untracked + Ignored(.gitignore 対象)両方を含める。

用途:

  • ビルド成果物を含めて完全にクリーンにする
  • node_modulesdist/ も一緒に退避
  • 完全な状態のスナップショット

⚠️ -a は大量のファイルを退避する可能性あり。慎重に使用。

使い分け早見表

コマンドtracked 変更untrackedignored
git stash
git stash -u
git stash -a

基本は -u を付けるのが安全。

デフォルトを変更

毎回 -u を打つのが面倒なら:

git config --global stash.showIncludeUntracked true

⚠️ この設定は git stash show の挙動を変えるもので、push の挙動自体は変わらない。

エイリアスで対処:

git config --global alias.st 'stash push -u'

これで git st -m "message" で untracked 含む stash に。


pop vs apply(決定的違い)

git stash pop

git stash pop
  • 最新の stash(stash@{0})を適用
  • stash スタックから削除

git stash apply

git stash apply
  • 最新の stash を適用
  • stash スタックに残す

使い分け

状況推奨
通常の一時退避pop
不安・実験的apply
複数ブランチに同じ変更を適用apply
conflict が心配apply

安全なパターン

# 1. apply で試す
git stash apply

# 2. 動作確認
npm test
# または手動確認

# 3. 問題なければ削除
git stash drop

これで失敗しても stash が残るため復旧可能。

特定 stash を適用

# インデックス指定
git stash pop stash@{2}
git stash apply stash@{2}

# 数値だけでもOK(Git 2.15+)
git stash pop 2
git stash apply 2

–index オプション

git stash apply --index

staged 状態も復元。デフォルトは全て unstaged に。

例:

# 退避前
Changes to be committed:
  new file: style.css
Changes not staged for commit:
  modified: index.html

git stash

# 復元後(デフォルト)
Changes not staged for commit:
  new file: style.css     ← unstaged になった
  modified: index.html

# --index で復元
Changes to be committed:
  new file: style.css     ← staged のまま
Changes not staged for commit:
  modified: index.html

厳密に元の状態に戻したい時に。

恒久化

git config --global stash.applyStat true

これで apply / pop が常に --index 付きの挙動に。


部分的 stash(-p / –patch)

hunk 単位で選択的に stash できる強力機能。

使い方

git stash push -p -m "部分stash"

Git が hunk ごとに聞いてきます:

Stash this hunk [y,n,q,a,d,e,?]?
キー動作
yこの hunk を stash
nこの hunk を stash しない
q中止
aこの後の hunk 全て yes
dこの後の hunk 全て no
e手動編集
shunk を分割
?ヘルプ

用途

  • 1つのファイルで2つの機能を開発中、片方だけ commit
  • 不要なデバッグコードだけ退避
  • 大きな変更を小さくコミットに分解

特定ファイルのみ stash

# パスを指定(Git 2.13+)
git stash push -m "config only" -- src/config.js

# 複数ファイル
git stash push -m "components" -- src/components/ src/styles/

# untracked も含めて特定パスだけ
git stash push -u -m "..." -- src/new/

大規模リポジトリで特定領域だけ退避したい時に便利。


staged / keep-index オプション

–staged(–S)

# インデックスに追加した変更だけ stash
git stash push --staged -m "staged のみ"

staged 状態の変更のみを退避、working tree の変更は残す:

Changes to be committed:
  modified: file1.js    ← stash される

Changes not staged:
  modified: file2.js    ← 残る

–keep-index(-k)

# staged はそのまま、working tree だけ stash
git stash push -k

staged 変更は working tree にも残る:

# 使いどころ:
# 段階的にcommit しつつ、各段階でテスト
git add --patch foo         # 一部だけ add
git stash push --keep-index # 残りを退避、add した分だけテスト
# テスト...
git commit -m "First part"
git stash pop               # 残りを取り出す
# 続きの作業...

より正確なテストの下で commit したい時に。


stash list / show

一覧表示

git stash list

出力:

stash@{0}: On main: WIP: user auth logic
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: On feature: WIP: navbar tweak
  • On <branch>: 明示的メッセージ付き
  • WIP on <branch>: デフォルトメッセージ

中身を確認

# 変更ファイル一覧(デフォルト)
git stash show stash@{0}

# 差分表示
git stash show -p stash@{0}
# または
git stash show --patch stash@{0}

# 統計
git stash show --stat stash@{0}

pop / apply する前に必ず中身を確認する習慣を。

git diff で見る

# 現在の作業ツリーとの差分
git diff stash@{0}

# 特定ファイルだけ
git diff stash@{0} -- src/config.js

詳細はLinuxでファイル差分を確認する方法(diff/colordiff/vimdiff)の記事も参照。


stash drop / clear

特定 stash を削除

git stash drop stash@{0}
git stash drop 0        # インデックスだけでも OK

# 複数削除は1つずつ
git stash drop 2  # 最も大きい番号から
git stash drop 1

⚠️ 削除は下から(大きい番号から)行う。理由:削除するとインデックスが繰り上がる。

全削除

git stash clear

⚠️ 全 stash が消える。実行前に必ず git stash list で確認。

削除後の救済

「消してしまった stash を復旧したい」→ 意外と可能:

# 到達不能な commit を検索
git fsck --unreachable | grep commit | cut -d' ' -f3 | \
  xargs git log --merges --no-walk --grep=WIP

# ハッシュを見つけたら
git stash apply <hash>
# または
git branch recovered <hash>

⚠️ Git のガベージコレクション(デフォルト 2週間)が走ると完全消滅。早めに救済


stash branch(安全な復旧)

長時間放置した stash や、conflict が心配な stash 向け:

git stash branch new-feature stash@{0}

これは以下を行います:

  1. stash 作成時のコミットから新ブランチ作成
  2. 作業ディレクトリと index に stash を適用
  3. 成功したらstash を drop

なぜ安全か

通常の pop は現在のブランチに適用するため、conflict の可能性大。branch は元のコンテキストで復元するため、conflict 発生しにくい

使いどころ

  • 昔の stash を復元したい
  • pop で大量の conflict になった
  • 長期間放置した stash を確実に復元

実例

# 昔の stash
git stash list
# stash@{5}: WIP on feature (2週間前)

# 現在のブランチで pop すると conflict 多発の予感

# 元のブランチ状態で復元
git stash branch old-feature stash@{5}

# → 2週間前の作業ツリー状態で新ブランチ「old-feature」に復元
# → conflict の可能性が最小化

conflict on pop の対処

発生パターン

git stash pop
# CONFLICT (content): Merge conflict in src/config.js

stash 作成時と現在のブランチで、同じ行を変更した場合。

対処法

# 1. 状態確認
git status

# 2. conflict 解決(通常の merge conflict と同じ)
vim src/config.js
# marker を消して正しい状態に

# 3. add
git add src/config.js

# 4. ⚠️ stash pop の場合、conflict が発生すると
#    stash が「削除されない」ので手動で drop
git stash drop

重要: pop で conflict が発生した時、stash は自動 drop されない。手動 drop を忘れると同じ stash が残り続ける。

詳細はgit merge conflict の解決方法の記事も参照。

apply なら drop 不要

git stash apply
# CONFLICT

# 解決 & add
# → stash はもともと残るので drop タイミングを選べる

pop よりも apply の方が事故時の対処が楽

やめたい場合

# 変更を全て破棄
git checkout .
git checkout HEAD -- .

# stash はまだあるので後で
git stash list

実践シナリオ

シナリオ1:緊急バグ対応

# feature ブランチで開発中
git status
# modified: src/user.js
# modified: src/api.js

# 緊急バグの連絡!
git stash push -u -m "WIP: user feature"

# main へ
git checkout main
# バグ修正
vim src/critical.js
git commit -am "Hotfix critical bug"
git push

# 元の作業に戻る
git checkout feature
git stash pop
# 続きから作業

シナリオ2:pull 前の一時退避

# 未commit の変更あり
git pull
# error: Your local changes to the following files would be overwritten by merge

# 退避 → pull → 復元
git stash push -u -m "before pull"
git pull
git stash pop

または --autostash オプション:

git pull --autostash

さらに恒久化:

git config --global rebase.autoStash true
git config --global pull.rebase true

これで stash 操作なしで pull が動く。詳細はgit rebase 使い方の記事も参照。

シナリオ3:複数ブランチに同じ変更を適用

# 便利な設定変更を作った
git stash push -m "shared config update"

# feature-a に適用
git checkout feature-a
git stash apply    # apply で残す

# feature-b に適用
git checkout feature-b
git stash apply

# 完了したら drop
git stash drop

シナリオ4:デバッグコードを一時退避

# デバッグprint を一時的に外す
git stash push -m "debug prints"

# クリーンな状態で動作確認
# ...

# デバッグに戻る
git stash pop

シナリオ5:部分的な commit(keep-index)

# 大きい変更のうち、一部だけ commit したい
git add --patch src/big_change.js
# → 選択的に add

# 残りを退避
git stash push -k
# または
git stash push --keep-index

# add した分だけテスト
npm test

# commit
git commit -m "Part 1: Add authentication"

# 残りを取り出して続き
git stash pop

シナリオ6:長期 stash を branch 化

# 忘れていた stash 発見
git stash list
# stash@{3}: WIP on old-feature (2週間前)

# 別ブランチで安全に復元
git stash branch resurrected-feature stash@{3}

# 動作確認 → 続きの作業

シナリオ7:Rails 開発でのstash

# feature 開発中
git status
# modified: app/models/user.rb
# modified: db/migrate/xxx.rb  ← マイグレーション追加中

# 緊急pull が必要
git stash push -u -m "user model + migration"

# pull
git pull --rebase

# 復元
git stash pop

# マイグレーションを実行
bin/rails db:migrate

詳細はrails db:migrate 使い方の記事も参照。

シナリオ8:CI/CD 用のクリーンビルド

# 開発中の変更を退避してクリーンな状態でビルドテスト
git stash push -u -m "before clean build test"

# クリーンな状態でビルド
bundle install --deployment
bundle exec rspec

# 開発に戻る
git stash pop

シナリオ9:チームで共有したい変更(stashではダメ)

# ❌ stash はローカル限定なので共有不可
git stash push -m "for review"

# ✅ 別ブランチを作る
git checkout -b temp/review-me
git add .
git commit -m "WIP: for review"
git push origin temp/review-me

# チームメンバーが
git fetch origin
git checkout temp/review-me

または patch ファイル:

git stash show -p stash@{0} > work.patch
# 送信、相手が
git apply work.patch

詳細はscp vs rsync の記事も参照。

シナリオ10:Docker/Kamal デプロイ前のクリーン化

# 開発中の変更を退避
git stash push -u -m "WIP before deploy check"

# クリーンな状態でイメージビルド
kamal deploy

# 開発に戻る
git stash pop

詳細はKamal 2 デプロイの記事docker daemon 接続エラーの記事も参照。


推奨設定

# 基本設定
git config --global alias.st 'stash push -u'          # -u デフォルトの alias
git config --global rebase.autoStash true              # rebase 前に自動 stash
git config --global stash.showIncludeUntracked true    # show 時に untracked も表示
git config --global stash.showStat true                 # show 時に統計表示
git config --global stash.showPatch true                # show 時に差分表示

# 便利な alias
git config --global alias.sl 'stash list'
git config --global alias.sp 'stash pop'
git config --global alias.sa 'stash apply'
git config --global alias.ss 'stash show -p'
git config --global alias.sd 'stash drop'

短縮コマンド:

git st -m "WIP"        # stash push -u
git sl                 # stash list
git sp                 # stash pop
git ss                 # stash show -p

トラブルシューティング

新規ファイルが stash されない

# ❌
git stash
git status
# script.js が残る

# ✅
git stash -u

stash デフォルトの落とし穴。alias で -u を必ず付ける。

stash が消えた(drop / clear した)

# 到達不能な commit 検索
git fsck --unreachable | grep commit | cut -d' ' -f3 | \
  xargs git log --merges --no-walk --grep=WIP

見つかったら:

git stash apply <hash>

早めに実行(GC で消滅)。

pop で conflict、stash が消えた?

# stash は残っている(pop で conflict 時は自動削除されない)
git stash list

# もし本当に消えている
git fsck --unreachable | grep commit

「stash が空です」

git stash pop
# No stash entries found

→ 現在の Git config で見えていない可能性。stash list で確認、または .git/logs/refs/stash を直接見る。

stash が多すぎる

git stash list
# stash@{0} ... stash@{50}

stash hygiene が悪い。定期的に整理:

# 古いのから確認
git stash show -p stash@{30}

# 不要ならdrop
git stash drop stash@{30}

# 全部いらないなら
git stash clear

⚠️ clear は復旧困難。必ず確認してから。

別マシンから stash にアクセスしたい

不可能。stash は各マシンローカル。別ブランチを push して対応。

部分的な stash が難しい

git stash -p
# → 対話式で選択

# または、いったん add してから stash
git add --patch
git stash push --keep-index -m "残り"
git commit -m "add したもの"
git stash pop

stash message を書き換えたい

直接編集は困難。以下のワークアラウンド:

# 適用してブランチ化 → 好きに操作
git stash branch new-branch stash@{0}

または apply して新規 stash 作成:

git stash apply stash@{0}
git stash drop stash@{0}
git stash push -m "新メッセージ"

よくある質問(FAQ)

Q1. stash pop と apply、どっちを使うべき?

  • 日常的な使用: pop(適用+削除)
  • 不安な時: apply(残す)→ 動作確認後 drop
  • 複数ブランチに適用: apply

初心者は apply から始めるのが安全。

Q2. git stash save は使ってはいけない?

Git 2.16 以降、save非推奨。同じ機能は push で実現:

# ❌ save は使わない
git stash save "message"

# ✅ push を使う
git stash push -m "message"

save はまだ動作するが、いずれ削除される可能性。

Q3. untracked ファイルを毎回含めたい

# alias で
git config --global alias.st 'stash push -u'

これで git ststash push -u になる。

Q4. stash した内容を確認

git stash show -p stash@{0}
# 差分表示

git stash show stash@{0}
# ファイル一覧

Q5. 特定ファイルだけ pop したい

# 特定ファイルだけ取り出し(Git 2.13+)
git checkout stash@{0} -- path/to/file

# 全体は stash に残る

Q6. チームで stash を共有

stash は共有不可。代わりに:

# 別ブランチを push
git checkout -b temp/wip
git add .
git commit -m "WIP"
git push origin temp/wip

# または patch
git stash show -p > work.patch
# 相手が
git apply work.patch

Q7. stash が「dirty」で困る

作業状態が中途半端。整理:

# 現状確認
git stash list
# stash@{0}: WIP on main...
# stash@{1}: WIP on main...
# ...

# 中身確認して drop
git stash show -p stash@{5}
git stash drop stash@{5}

Q8. stash と branch、どっちを使う?

用途推奨
短時間の退避(分〜時間)stash
長時間の作業(日〜週)ブランチ
チームと共有ブランチ
バックアップブランチ
CI/CD の対象ブランチ

長時間ならブランチを作るのが正解

Q9. rebase 中に stash できる?

git rebase main
# 中断
git stash push -m "rebase pause"

# 難しい状況、非推奨

rebase 中の stash は避ける。まず --abort するか、--autostash を使う。

Q10. reflog で stash を復旧

# stash の reflog
git reflog show stash

# 特定 stash を復活
git checkout stash@{2.hours.ago}

Q11. stash が Git GUI で見えない

各ツールの表示設定確認:

  • GitKraken: サイドバー
  • SourceTree: 左メニュー
  • VS Code: Git ペインの stash 項目

Q12. IDE との統合

  • VS Code: Git: Stash コマンド
  • JetBrains: VCS メニュー → Git → Stash
  • Rider: Git → Uncommitted Changes → Stash

参考リンク・関連資料

Git 公式

関連記事(本サイト)


まとめ

git stash の使い方、要点を再整理します。

基本コマンド 10選

git stash push -m "message"       # メッセージ付き stash
git stash push -u -m "message"    # untracked も含める(推奨)
git stash list                    # 一覧
git stash show -p stash@{0}       # 中身確認
git stash pop                     # 適用 + 削除
git stash apply                   # 適用 + 残す
git stash apply stash@{2}         # 特定 stash 適用
git stash drop stash@{0}          # 削除
git stash clear                   # 全削除
git stash branch <name> stash@{0} # 別ブランチで復元

pop vs apply 使い分け

状況推奨
通常の一時退避pop
不安な時apply → 確認 → drop
複数ブランチに適用apply

3つの重要な落とし穴

  1. untracked ファイルはデフォルトで含まれない-u 必須
  2. pop で conflict 時、stash は削除されない → 手動 drop 必要
  3. stash はローカル限定 → チーム共有不可

現代の推奨

# ❌ 非推奨
git stash save "message"

# ✅ 推奨
git stash push -m "message"
git stash push -u -m "message"

stash かブランチか

短時間(分〜時間)→ stash
長時間(日〜週) → ブランチ
チーム共有       → ブランチ
バックアップ    → ブランチ

推奨設定

git config --global rebase.autoStash true      # rebase 時に自動stash
git config --global alias.st 'stash push -u'   # untracked 込み

実務ワークフロー

1. 開発中に緊急割り込み
    → git stash push -u -m "WIP: ..."
2. 別作業(緊急対応、pull 等)
3. 元の作業に戻る
    → git stash pop(or apply → 確認 → drop)
4. Conflict あれば解決 → add → drop(pop の場合手動)

事故時の救済

# 削除してしまった stash を復旧
git fsck --unreachable | grep commit | cut -d' ' -f3 | \
  xargs git log --merges --no-walk --grep=WIP

# 早めに実行(GC で消滅)

これらの知識は、日常の Git 操作・チーム開発・緊急バグ対応・実験的作業・CI/CD など、あらゆる場面で活用できます。本記事をブックマークしておけば、git stash恐れず自在に使いこなせるようになります。


本記事は2026年6月時点の情報をもとに、Git 2.40+ での動作確認・公式ドキュメントに基づき作成しています。Git のバージョンによって挙動が異なる場合があるため、最新の情報はGit公式ドキュメントもあわせてご確認ください。