頑張らないために頑張る

ゆるく頑張ります

Git stashの基本

Posted at — Aug 25, 2025

「機能開発の途中だけど、急ぎで別のバグ修正を頼まれた」「まだコミットしたくないけど、他のブランチの様子をちょっと見たい」などなど、開発現場ではこんなふうに作業を中断せざるを得ない場面が頻繁に訪れます。そんな時、あなたはどうしていますか? 中途半端な状態で無理やりコミットしたり、変更内容をどこかに手動でコピーしたりしていませんか?

そんな悩みを一発で解決してくれる魔法のような機能が、Gitの git stash(スタッシュ) です。この記事を読めば、git stashの概念から応用までを完全にマスターし、あなたの開発効率を劇的に向上させることができます。

git stashとは

git stashとは、まだコミットしていない作業内容(変更)を、一時的に別の場所に退避させておく ための機能です。

たとえば、あなたは今、机の上でプラモデルを作っています。パーツを切り出し、接着剤でくっつけ始めたところです(=コーディング中)。そこへ急な来客があり、机をすぐに片付けなければならなくなりました(=緊急の修正依頼)。この時、作りかけのプラモデルを箱にしまって、机の上を一旦まっさらにしますよね。来客対応が終わったら、また箱から取り出して作業を再開できます。

この「一時的に箱にしまう」という行為が、まさにgit stashです。git stashを使うと、作業ディレクトリを最後にコミットしたきれいな状態に戻せるので、安心して別の作業に取り掛かることができます。

git stashの基本的な使い方

git stashの操作は非常にシンプルです。基本的な流れは以下の3ステップです。

  1. 退避
  2. 確認
  3. 復元

作業を退避する (git stash / git stash push)

現在のブランチで行った変更を一時退避させます。最も基本的なコマンドは git stash ですが、これは git stash push の省略形です。

どの作業を退避させたか後で分かるように、メッセージを付けておくことを推奨します。メッセージを付けるには push サブコマンドと -m ( --message ) オプションを使います。メッセージを付与しておかないと、後で見返したときに「これなんの履歴だっけ?」となること請け合いです。とくに、git stash popせずstashリストに残りっぱなしだとこうなりがち。

# メッセージを付けてstashに退避
$ git stash push -m "WIP: ログイン画面のUI調整中"
Saved working directory and index state On feature/new-login: WIP: ログイン画面のUI調整中

もちろん、メッセージ無しで退避することも可能です。

# メッセージ無しでstashに退避
$ git stash
# or
$ git stash push

すぐgit stash popするなら、このような方法でも問題ないと思います。

savepush の違い

以前は git stash save "メッセージ" というコマンドが使われていましたが、現在は非推奨(deprecated)とされています。機能は git stash push -m "メッセージ" と同じですが、今後は push を使うようにしましょう。

退避した作業一覧を見る (git stash list)

退避させた作業は、git stashのリストに積み重なっていきます。listコマンドで確認できます。

$ git stash list
stash@{0}: On feature/new-login: WIP: ログイン画面のUI調整中
stash@{1}: On feature/old-feature: WIP on feature/old-feature: ...

stash@{0}が一番新しく退避した作業です。古いものほど数字が大きくなります。

退避した作業を復元する (git stash apply / git stash pop)

退避した作業を元に戻して、作業を再開します。復元には2つのコマンドがあります。

# 最新のstashを復元(stashはリストに残る)
$ git stash apply

# 最新のstashを復元(stashはリストから削除される)
$ git stash pop

デフォルトでは最新のstash@{0}が復元されます。どちらのコマンドを使うべきかについては、次のセクションで詳しく解説します。

pop vs apply:どちらを使うべき?

git stashを復元する2つのコマンド、popapplyには明確な違いがあります。

使い分けのポイント

コマンド 動作 おすすめのシーン
git stash pop 復元して、リストから削除する 基本はこれ。退避した作業を元に戻して作業を再開するとき
git stash apply 復元するが、リストには残したまま 同じ変更を複数のブランチに適用したいとき

特別な理由がなければ、まずはpopを使えばいいと覚えておけば、とりあえず問題ないと思います。

知っておくと便利なgit stash応用テクニック

基本操作を覚えたら、さらに便利な応用テクニックもマスターしましょう。

特定のstashを操作する

stash@{n}のように番号を指定することで、最新ではないstashを操作できます。

# 2番目(stash@{1})のstashの変更内容を確認
$ git stash show stash@{1}

# 3番目(stash@{2})のstashを復元(リストには残る)
$ git stash apply stash@{2}

# 2番目(stash@{1})のstashを削除
$ git stash drop stash@{1}

Untrackedファイルも一緒に退避する (-u)

git addしていない新規作成ファイル(Untracked files)は、デフォルトではgit stashの対象になりません。これらも一緒に退避させたい場合は-uオプションを付けます。

# 未追跡ファイルも含めてstash
$ git stash -u
# or
$ git stash --include-untracked

ケースバイケースではあるものの、個人的には比較的よく利用するオプションです。というのも、しっかりこまめにgit addしてないからです_( _´ω`)_ペショ

.gitignoreのファイルも(ほぼ)すべて退避する (-a)

.gitignoreで意図的に無視しているファイルも含め、すべての変更を退避させたい場合は-aオプションを使います。

# 無視ファイル、未追跡ファイルも含めて全てstash
$ git stash -a
# or
$ git stash --all

たとえば、「デバッグ中に急遽別のバグ対応をしなければならない」という場合が、このオプションを利用するケースでしょう。大抵、デバッグ用のコードなどは.gitignoreで意図的に無視している場合が多いため、「デバッグ途中の状態を保持しておきたい」となると、.gitignoreで意図的に無視しているファイルも退避する対象に含める必要があるからです。逆に言えば、そのようなケースでない場合は、あまり利用しないオプションだと思います。

ステージングした変更だけを退避する (-S / --staged )

git addした変更(ステージングエリアにある変更)のみgit stashしたい場合において、非常に便利なオプションです。

git addしたものの、コミットメッセージを考えたり、関連する変更をもう少し加えたりしたい。でも、ステージングしていない変更(デバッグ用のコードなど)はgit stashに含めたくない…そんな場面で役立ちます。

# 1. 変更Aと変更Bを行う
# (file.txt に A を追記, debug.log に B を追記)

# 2. コミットしたい変更Aだけをステージング
$ git add file.txt

# 3. ステージングした変更だけをstash
$ git stash --staged
Saved working directory and index state WIP on main: ...

# この時点で、file.txtの変更は退避され、
# debug.logの変更は作業ディレクトリに残ったままになる

applypopでステージング状態も復元する (--index)

git stashする際にステージングされていた変更は、applypopで復元する際にもその状態を維持したいですよね。そんな時に使うのが--indexオプションです。

通常、git stash popを実行すると、退避した変更はすべて「ステージングされていない状態」で作業ディレクトリに戻ります。

しかし、--indexオプションを付けて復元すると、git stashした時点でのステージング状態が再現されます。

# 1. file_A.txt と file_B.txt を変更
# 2. file_A.txt のみステージング
$ git add file_A.txt

# 3. stashに退避
$ git stash

# ... (別の作業) ...

# 4. --index を付けて復元
$ git stash pop --index

# この時点で `git status` を確認すると...
# Changes to be committed:
#   (use "git restore --staged <file>..." to unstage)
#         modified:   file_A.txt  <- ステージング状態が復元されている。
#
# 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:   file_B.txt

このオプションを使えば、「この変更はコミットする予定だった」という状態まで正確に復元できるため、作業の再開がよりスムーズになります。

stashを完全に消去する (git stash clear)

溜まったstashをすべて一括で削除します。一度削除すると元に戻せないので注意して利用してください。というか、あまりこのコマンドは個人的には使ったことがありません。git stash popして残さないからかもしれません。

# 全てのstashを削除
$ git stash clear

こんな時にgit stash

具体的なシナリオでgit stashの使い方を見てみましょう。

緊急のバグ修正

あなたはfeature/new-designブランチで新デザインの実装中です。しかし、上司から「公開中のサイトで緊急のバグが見つかったから、すぐに修正して。」と頼まれました。このとき、現在対応している修正をいったん横において、バグ対応する必要があります。このようなときにgit stashを利用します。

# 1. 現在の作業をstashに退避
$ git stash push -m "WIP: 新デザインのヘッダー実装中"

# 2. メインブランチに移動し、最新の状態にする
$ git switch main
$ git pull origin main

# 3. バグ修正用のブランチを作成して修正作業
$ git switch -c hotfix/critical-bug
# ... (バグを修正してコミット)
$ git commit -am "Fix: 致命的なバグを修正"

# 4. mainブランチにマージしてプッシュ
$ git switch main
$ git merge hotfix/critical-bug
$ git push origin main

# 5. 元の作業ブランチに戻る
$ git switch feature/new-design

# 6. 退避しておいた作業を復元して再開。
$ git stash pop

これで、コミットを汚すことなく、スマートに緊急対応ができました。

まだコミットしたくないが、別のブランチを確認したい

上手く行かないデバッグの気分転換に、別のブランチの進捗状況を確認したいとします。その際は、中途半端になっている現在のブランチをどうにかしないといけません。そのようなときにgit stashを利用します。

# 1. 中途半端な作業を一時退避
$ git stash push -m "WIP: feature/A のロジック実装途中"

# 2. 確認したいブランチに移動
$ git switch feature/B
# ... (コードの確認や議論) ...

# 3. 元の作業ブランチに戻り、作業を再開
$ git switch feature/A
$ git stash pop

まとめ

git stashは、日々の開発業務で発生する「作業の中断」にスマートに対応するための必須ツールです。

これらのポイントを押さえるだけで、あなたのGitライフはより快適で効率的なものになります。もう作業の中断を恐れる必要はありません。git stashを使いこなし、ワンランク上の開発者を目指しましょう。

参考

  1. Git stash
  2. 【git stash】コミットはせずに変更を退避したいとき
  3. Git Stash 完全ガイド & チートシート#新人エンジニア向け
  4. Git Stash
comments powered by Disqus