git stashで作業途中のコードを一時退避し、ブランチ切り替えを効率化する

git stashは、コミットしていない変更を一時的に保存し、作業ディレクトリをクリーンな状態に戻すコマンドです。この記事では、実務でよく発生する「途中の変更を保存したまま別ブランチに移動したい」という状況で、git stashを活用する具体的な方法と注意点を紹介します。

git stashとは:基本的な役割

git stashは、ステージングエリアとワーキングディレクトリの変更を一時的なスタック領域に保存し、変更前の状態に戻すツールです。コミットする準備ができていない「途中段階の作業」を安全に退避できます。

使うべき場面と使うべきでない場面

使うべき場面:

  • 別ブランチで緊急対応が必要になったとき
  • コードレビュー前に別の機能を試したいとき
  • 実験的な変更を一時保存してリセットしたいとき
  • チームメンバーにコードを渡すため、作業ディレクトリをクリーンにしたいとき

使うべきでない場面:

  • 完成した機能をコミットせずに放置する(stashは長期保存向けではない)
  • 複数人で共有する重要な変更(git stashは個人ローカル環境専用)
  • 大規模な変更で履歴管理が必要な場合(通常のcommitを使うべき)

git stashの基本的な使い方

1. 変更を一時退避する(基本形)

現在の作業ディレクトリの変更(ステージ済み・未ステージ両方)をstashに保存します:

git stash

これでワーキングディレクトリがクリーンな状態に戻ります。stashには「WIP on branch-name」というメッセージが自動付与されます。

2. わかりやすい説明を付けてstashする

複数のstashを管理するとき、何の変更か一目でわかるようにするため、説明メッセージを付けることを推奨します:

git stash save "ユーザー認証機能の実装途中"

または、より新しいGitバージョン(2.13以上)では:

git stash push -m "ユーザー認証機能の実装途中"

3. 保存されたstashを確認する

現在保存されているstashの一覧を表示します:

git stash list

実行結果の例:

stash@{0}: On feature/user-auth: ユーザー認証機能の実装途中
stash@{1}: WIP on develop: database接続設定
stash@{2}: On hotfix/bug-fix: ログイン画面のバグ修正

4. stashの内容を確認する

特定のstashで何が変更されているか確認したいとき:

git stash show stash@{0}

さらに詳細な差分を見たいときは、-pオプションを追加します:

git stash show -p stash@{0}

5. stashを復元する

最新のstashをワーキングディレクトリに復元します:

git stash pop

popは復元後、stashを削除します。復元だけして保持したい場合は:

git stash apply stash@{0}

特定のstashを復元する場合は、インデックスを指定します:

git stash apply stash@{1}

実務でよくあるユースケース

ケース1: 緊急バグ修正で別ブランチに切り替える

feature/new-featureで実装途中のコードがあるが、本番環境のバグ報告が来た場合:

# 現在の変更を退避
git stash push -m "新機能実装途中:ユーザー管理画面"

# develop/hotfixブランチに移動
git checkout hotfix/critical-bug

# バグ修正作業...

# feature/new-featureに戻る
git checkout feature/new-feature

# 退避した変更を復元
git stash pop

ケース2: 複数の実験的変更を並行管理する

異なる実装方法を試したいとき:

# 実装方法A を試す
# ...コード編集...
git stash push -m "実装方法A:ReduxベースのState管理"

# 実装方法B を試す
# ...別のコード編集...
git stash push -m "実装方法B:ZustandベースのState管理"

# 一覧で比較
git stash list

# 方法Aを復元して比較
git stash apply stash@{1}

ハマりやすいポイントと解決策

問題1: stash popでコンフリクトが発生する

stash復元後に他ブランチの変更と競合することがあります。その場合、マージのように競合を手動で解決する必要があります:

# コンフリクト表示を確認
git status

# エディタで競合を解決

# 解決後、stashを削除
git stash drop stash@{0}

問題2: stashを誤って削除してしまった

git reflogを使い、削除されたstashを復元できる場合があります:

git reflog

削除されたstashの参照を見つけて復元します(ローカルのみ有効)。ただし、確実性は保証されないため、重要な変更は常にコミットすることを推奨します。

問題3: 新規ファイルがstashに含まれない

git stashはデフォルトでトラッキングされていないファイル(新規ファイル)を保存しません。新規ファイルも含めて保存する場合:

git stash push -u -m "新規ファイル含めて退避"

# または
git stash --include-untracked

git stashと類似ツールの比較

git stash vs git commit --amend: stashは一時的な退避用。重要な変更はcommitで記録すべき。

git stash vs git cherry-pick cherry-pickは特定のコミットを別ブランチに適用する異なるユースケース。stashは「未コミット状態」を扱う。

git stash を使った効率的なワークフロー

# 開発中、新しいタスクが入った場合の標準手順
git status  # 現在の状態確認

# 現在の作業を詳細メッセージ付きで退避
git stash push -m "タスク#123:支払い機能の決済フロー実装"

# 別のブランチで作業
git checkout develop
git checkout -b hotfix/urgent-issue

# 修正完了後、元の作業に戻る
git checkout feature/payment-flow
git stash list  # 保存されたstashを確認
git stash apply stash@{0}  # 復元(削除されない)

# 復元後、確認して問題がなければ
git stash drop stash@{0}  # stashを削除

よくある質問

A: popは復元後、そのstashを削除します。applyは復元後も保持します。誤りが心配な場合はapplyで確認してからdropで削除する流れが安全です。

A: いいえ。git stashはローカルリポジトリのみです。チームメンバーと共有したい場合は、git commitしてpushするか、パッチファイル化(git format-patch)する必要があります。

A: 復元直後であればgit reset --hard HEADでリセットできます。その後、正しいブランチに切り替えてgit stash applyしてください。

まとめ

  • git stashは未コミット変更を一時的に保存し、ワーキングディレクトリをクリーンにするツール
  • 緊急対応で別ブランチに切り替える必要があるとき、最も効率的な方法
  • git stash push -m "説明"で複数stashを管理しやすくする習慣をつける
  • popapplyを使い分け、popは削除されるため確認後推奨
  • 新規ファイルも含める場合は-u--include-untracked)オプションを追加
  • 重要な変更は必ずcommitで記録し、stashに長期依存しない
  • stashはローカルのみで、チーム共有にはcommitが必須

git stashはシンプルながら実務で毎日活躍するツールです。Gitの公式ドキュメントも参照して、さらに詳しい使い方を確認することをお勧めします。

K
AWS・Python・生成AIを専門とするソフトウェアエンジニア。AI・クラウド・開発ワークフローの実践ガイドを執筆しています。詳しく見る →