🐧 Linux 総合学習プラットフォーム
Git バージョン管理 ・ 中級

作業を一時退避する(stash)

作業の途中でも、コミットするほどまとまっていない変更を抱えたままブランチを切り替えたい場面は多くあります。そんなときに使うのが git stash です。変更をいったん棚上げして作業ツリーをきれいな状態に戻し、あとで呼び戻せます。stash list・pop・apply の使い分けと、忘れがちな untracked ファイルの扱いまで押さえます。

作業の途中で急に別のブランチに切り替えたくなることがある。急ぎのバグ報告が来た、上司に別件を頼まれた、そんな場面だ。でも今の変更はまだコミットするほどまとまっていない。

こういうとき git switch や git checkout でブランチを移ろうとすると、変更内容によっては「ローカルの変更が上書きされるので切り替えられません」と Git に止められることがある。かといって中途半端な内容をコミットするのも気が引ける。

無理やりコミットしてしまうと、あとで履歴を見返したときに「バリデーション途中」「あとで直す」のようなメッセージが並び、履歴の質が落ちてしまう。そうかといって変更を破棄するのも論外だ。せっかく書いたコードを失いたくはない。

そこで使うのが git stash だ。作業ツリーの変更をいったん退避棚にしまい、作業ツリーをきれいな状態(直前のコミットの状態)に戻す。棚にしまった内容はあとから呼び戻せるので、コミットするほどでもない作業を安全に一時中断できる。

🔗
たとえ作業机の書類を、コミットは「ファイルに綴じて保管」、stash は「とりあえず引き出しにしまって机を片付ける」ようなものだ。あとで引き出しを開ければ、続きから再開できる。
💡
ポイントgit stash はコミットではない。作業ツリーの変更を一時的な退避スタックに積むだけの、あくまで仮置きの仕組みだ。

🗄️ stash の基本操作

退避するコマンドは git stash push だ。単に git stash と打っても同じ意味になるが、push を明示したほうが「何をしているか」が分かりやすい。

変更を退避してメッセージを付ける $ git stash push -m "ログイン画面の途中作業" Saved working directory and index state On feature/login: ログイン画面の途中作業

退避すると、変更していたファイルは直前のコミットの状態に戻る。git status を打っても「変更なし」と表示され、作業ツリーはまっさらに見える。だが変更が消えたわけではなく、退避スタックの中に積まれているだけだ。

退避した一覧を見るには git stash list を使う。退避するたびに stash@{0}、stash@{1}……と番号が振られ、新しいものほど 0 に近い番号になる。

退避一覧を確認する $ git stash list stash@{0}: On feature/login: ログイン画面の途中作業 stash@{1}: On main: WIP on main: 3a9f1c2 バリデーション修正

この番号は固定ではなく、退避を追加したり取り出したりするたびに詰め直される。だから「stash@{2} だったはず」と番号だけを覚えて放置すると、あとで別のものを指してしまうことがある。作業のたびに list で確認する癖をつけておくと安全だ。

作業ツリー途中の変更ありstash push退避スタックstash@{0}stash@{1}新しい順に0番switch別ブランチへ安全に移動退避してから移動すれば、切り替えエラーを避けられる

🔁 pop と apply の違い

退避した変更を作業ツリーに戻すコマンドは2つある。git stash pop と git stash apply だ。この2つの違いを理解せずに使うと、あとで「同じ変更が二重に残っている」と混乱しやすい。

git stash pop は、変更を作業ツリーに戻したうえで、退避スタックからその分を削除する。使い終わった引き出しの中身を空にするイメージだ。基本的にはこちらを使えば十分なことが多い。

git stash apply は、変更を作業ツリーに戻すが、退避スタックには残したままにする。同じ退避内容を複数のブランチに適用したいときや、念のため退避を消さずに残しておきたいときに使う。

💡
ポイント迷ったら pop でよい。ただし「この退避を別のブランチにも当てたい」など、スタックに残す必要がある場面だけ apply を選ぶ。
stash@{0}退避中の変更pop作業ツリーへ戻すスタックからは削除apply作業ツリーへ戻すスタックには残る迷ったら pop他ブランチにも使い回すなら apply

適用したい退避を番号で指定することもできる。何も指定しなければ一番新しい stash@{0} が対象になる。

特定の退避を指定して戻す $ git stash pop stash@{1} On main: 変更を適用しました

📁 untracked ファイルの注意点

git stash push はデフォルトでは、Git がまだ追跡していない新規ファイル(untracked ファイル)を退避対象に含めない。新しく作ったファイルだけがそのまま作業ツリーに残ってしまい、「あれ、退避したのに新規ファイルは消えていない」と戸惑うことがある。

これは初めて stash を使う人がほぼ必ずつまずくポイントだ。既存ファイルの修正は綺麗に退避されたのに、追加したファイルだけ作業ツリーに残っているので、別ブランチに切り替えたときに「見覚えのない新規ファイルが紛れ込んでいる」ように見えてしまう。

新規ファイルも含めて丸ごと退避したいときは -u オプション(--include-untracked の略)を付ける。

新規ファイルも含めて退避する $ git stash push -u -m "新規コンポーネント含む途中作業" Saved working directory and index state On feature/login: 新規コンポーネント含む途中作業
つまずき.gitignore で無視しているファイル(ビルド生成物など)まで退避したい特殊なケースでは -a(--all)を使うが、日常的にはあまり使わない。基本は -u を覚えておけば十分だ。
コツ「新規ファイルを作った日の作業を退避するときは、必ず -u を付ける」とルール化しておくと、この落とし穴を毎回避けられる。

⚠️ 退避したまま忘れる事故

stash の一番の落とし穴は「退避したこと自体を忘れる」ことだ。作業ツリーがきれいに見えるので安心してしまい、そのまま何日も stash@{3} のような古い退避がスタックに積み上がっていく。

コツ定期的に git stash list を確認する習慣をつけるとよい。中身が思い出せない退避は git stash show -p stash@{0} で差分を覗いてから、必要か判断する。
退避の中身を差分として確認する $ git stash show -p stash@{0} diff --git a/login.css b/login.css -color: gray; +color: navy;
つまずき不要になった退避は git stash drop stash@{0} で個別に破棄できる。全部まとめて消すなら git stash clear だが、これは元に戻せないので実行前に一覧を必ず見直すこと。

退避は便利だが、あくまで一時的な仮置き場所であって長期保管には向かない。区切りのよいところで pop してコミットするか、不要なら drop するか、こまめに整理する意識を持つと事故を防げる。

慣れてくると、stash はブランチ切り替えの保険としてだけでなく、「この変更、いったん戻して素の状態で挙動を確認したい」といった調査目的にも使えるようになる。退避と復元が軽い操作だからこそ、気軽に試せる場面が広がっていく。

💥 pop で衝突が起きたとき

stash pop は多くの場合すんなり成功するが、退避してから元のブランチ側でも同じ箇所を触っていた場合、戻すときに競合(コンフリクト)が起きることがある。

この場合、Git は「自動では戻せませんでした」と伝え、該当ファイルにコンフリクトを示す印を残す。落ち着いてその印の部分を見比べ、どちらの内容を残すか決めて手直しすればよい。

つまずきpop がコンフリクトで失敗した場合、退避した内容はまだスタックから消えていない。慌てて何度もpopし直す必要はなく、まずは表示された案内に従って競合箇所を1つずつ解消すれば大丈夫だ。
コツ競合が怖いときは、まず pop の代わりに apply で試すという手もある。apply なら失敗してもスタックに元の退避がそのまま残るので、いったん作業ツリーの変更を破棄して仕切り直しやすい。

🌿 特定ファイルだけを退避する

作業ツリー全体ではなく、特定のファイルだけを退避したい場面もある。git stash push には対象を絞り込むための指定方法が用意されている。

特定のファイルだけを退避する $ git stash push -m "設定ファイルだけ退避" -- config.js Saved working directory and index state On main: 設定ファイルだけ退避

-- のあとにファイルパスを並べると、それ以外の変更は作業ツリーに残したまま、指定したファイルの変更だけを退避できる。複数の作業を同時に進めていて、一部だけを別のコミットに分けたいときに役立つ。

💡
ポイントstash は「全部まとめて退避」だけでなく、「一部だけ選んで退避」もできる。作業を整理したいときの小さな武器になる。

❓ よくある疑問

「stashした内容はどこまで残るのか」という疑問もよく出る。stashはリポジトリの中に保存される情報であり、パソコンを再起動しても消えない。ただし clone し直した別の場所には引き継がれない、あくまでそのリポジトリのローカルな作業領域限定の仕組みだ。

「ブランチを切り替えなくても stash は使えるのか」という疑問もある。答えはイエスで、同じブランチのまま「いったん最初の状態に戻して確認したい」というときにも普通に使える。ブランチ移動は stash の主な用途の1つに過ぎない。

この項目に出てくる用語

stash エントリすたっしゅえんとり
git stash で退避した1件分の変更のかたまり。stash@{0} のように番号で管理される。
未追跡ファイルみついせきふぁいる
Gitがまだ一度も管理対象に加えていない新規ファイルのこと。英語では untracked。
作業ツリーがきれいさぎょうつりーがきれい
git statusで表示される、コミットしていない変更が一切ない状態を指す言い回し。

関連コマンド

git stash

▶ 学習アプリでこの続きを学ぶ・演習する