git stash完全ガイド:作業を一時退避して開発効率を劇的に向上させる方法【2025年最新版】

git stash完全解説

git stashでお困りですか?「一時保存した変更が消えた」「複数のstashの管理が難しい」「適用時にコンフリクト」といった悩みを抱えるエンジニアは多いものです。

実は、git stashは作業の中断と再開を自在にコントロールできる強力なコマンドです。この記事では、実務で本当に使えるgit stashの活用法を、豊富な実例とともに徹底解説します。

最後まで読むことで、git stashをマスターし、コンテキストスイッチ時間80%削減できるようになります。


目次

🎯 この記事で学べること

  • git stashの基本的な使い方と動作原理
  • 実務で使える実践的なオプションとテクニック
  • よくあるエラーの解決方法とトラブルシューティング
  • チーム開発で役立つベストプラクティス
  • 複雑な状況での応用的な使い方

📋 前提知識

  • Gitの基本概念(リポジトリ、コミット、ブランチ)の理解
  • コマンドラインの基本操作
  • git add、git commit、git checkoutの基本的な使い方

読了時間: 約15分
難易度: (中級)


🚀 git stashとは?基本概念の理解

概要と役割

git stashは、現在の作業中の変更を一時的に退避(stash)するGitのコマンドです。コミットする準備ができていない変更を一時的に保存し、クリーンな作業ディレクトリに戻すことができます。

開発中によくある「今の作業を中断して別の作業をしなければならない」という状況で威力を発揮します。例えば、新機能の開発中に緊急のバグ修正が入った場合、現在の作業を一時退避してバグ修正を行い、その後元の作業に戻ることができます。

動作原理の図解

他のコマンドとの関係

関連コマンド役割使い分け
git commit変更を履歴に記録作業が完了した時
git checkoutブランチ切り替えstash後のクリーンな状態で実行
git reset変更を取り消し完全に破棄したい時
git branchブランチ操作stashからブランチ作成も可能

📝 基本的な使い方

コマンドの基本構文

git stash [サブコマンド] [オプション]

最もシンプルな使用例

# 基本形
git stash

# 実行例
$ git stash
Saved working directory and index state WIP on main: abc1234 Latest commit message

解説:

  • Saved working directory and index state: 作業ディレクトリとインデックスの状態が保存されたことを示す
  • WIP on main: Work In Progress(作業中)を意味し、mainブランチでの作業であることを示す
  • abc1234: 退避時点の最新コミットのハッシュ値

よく使うオプション一覧

オプション説明使用例
-u, --include-untracked未追跡ファイルも含めるgit stash -u
-a, --all無視ファイルも含めるgit stash -a
-m, --messageメッセージを付けるgit stash -m "認証機能の途中"
-p, --patch対話的に選択git stash -p

🔧 実践的な使用例

ケース1: 緊急のバグ修正への対応

シナリオ: 新機能の開発中に、本番環境で緊急のバグが発見され、すぐに修正が必要になった。

# 1. 現在の状態を確認
$ git status
On branch feature/user-auth
Changes not staged for commit:
  modified:   src/auth.js
  modified:   src/components/LoginForm.js
Untracked files:
  src/utils/validation.js

# 2. 作業を退避(未追跡ファイルも含む)
$ git stash -u -m "認証機能の実装途中"
Saved working directory and index state On feature/user-auth: 認証機能の実装途中

# 3. mainブランチに切り替えてバグ修正
$ git checkout main
Switched to branch 'main'

# 4. バグ修正を実施
$ vim src/api/users.js
$ git add src/api/users.js
$ git commit -m "fix: ユーザーAPI の null pointer エラーを修正"

# 5. 元のブランチに戻る
$ git checkout feature/user-auth

# 6. 退避した作業を復元
$ git stash pop
On branch feature/user-auth
Changes not staged for commit:
  modified:   src/auth.js
  modified:   src/components/LoginForm.js
Untracked files:
  src/utils/validation.js
Dropped refs/stash@{0} (5d3e1f4...)

ポイント:

  • -uオプションで未追跡ファイルも退避できる
  • メッセージを付けることで、複数のstashがある場合に識別しやすい
  • popを使うと適用と同時にstashから削除される

ケース2: 複数の作業を管理

シナリオ: 複数の機能開発を並行して進めており、それぞれの作業を切り替えながら進める必要がある。

# 1. 機能Aの作業を退避
$ git stash push -m "機能A: データベース接続部分"

# 2. 機能Bの作業を退避
$ git stash push -m "機能B: UIコンポーネントの実装"

# 3. stashリストを確認
$ git stash list
stash@{0}: On main: 機能B: UIコンポーネントの実装
stash@{1}: On main: 機能A: データベース接続部分

# 4. 特定のstashの内容を確認
$ git stash show stash@{1}
 src/db/connection.js | 25 +++++++++++++++++++++++++
 src/db/models.js     | 15 +++++++++++++++
 2 files changed, 40 insertions(+)

# 5. 詳細な差分を確認
$ git stash show -p stash@{1}
diff --git a/src/db/connection.js b/src/db/connection.js
index abc1234..def5678 100644
--- a/src/db/connection.js
+++ b/src/db/connection.js
@@ -1,3 +1,28 @@
+const mongoose = require('mongoose');
+
+const connectDB = async () => {
+  try {
+    await mongoose.connect(process.env.MONGODB_URI, {
+      useNewUrlParser: true,
+      useUnifiedTopology: true
+    });
+    console.log('MongoDB connected successfully');
+  } catch (error) {
+    console.error('MongoDB connection error:', error);
+    process.exit(1);
+  }
+};
...

# 6. 機能Aの作業を再開
$ git stash apply stash@{1}

ポイント:

  • 複数のstashを管理する際は必ずメッセージを付ける
  • showコマンドで内容を確認してから適用する
  • applyを使えばstashを残したまま適用できる

ケース3: 部分的なstash(対話モード)

シナリオ: 複数のファイルを変更しているが、一部の変更だけを退避したい。

# 1. 対話モードでstashを開始
$ git stash -p

diff --git a/src/app.js b/src/app.js
index abc1234..def5678 100644
--- a/src/app.js
+++ b/src/app.js
@@ -10,6 +10,8 @@ const app = express();
 app.use(express.json());
 app.use(cors());

+// 新しいミドルウェアを追加
+app.use(authMiddleware);
+
 app.get('/', (req, res) => {
   res.send('Hello World');
Stash this hunk [y,n,q,a,d,/,e,?]? y

diff --git a/src/config.js b/src/config.js
index bcd5678..efg9012 100644
--- a/src/config.js
+++ b/src/config.js
@@ -5,4 +5,5 @@ module.exports = {
   port: process.env.PORT || 3000,
   database: process.env.DATABASE_URL,
+  secretKey: process.env.SECRET_KEY,
 };
Stash this hunk [y,n,q,a,d,/,e,?]? n

# 2. 結果を確認
$ git status
On branch main
Changes not staged for commit:
  modified:   src/config.js

対話モードのオプション:

  • y – この変更をstashする
  • n – この変更をstashしない
  • q – 終了
  • a – このファイルの残りの変更をすべてstash
  • d – このファイルの残りの変更をすべてスキップ
  • ? – ヘルプを表示

🔍 トラブルシューティング

エラー1: マージコンフリクト

エラー内容:

error: Your local changes to the following files would be overwritten by merge:
    src/components/Header.js
Please commit your changes or stash them before you merge.

原因:

  • stashを適用しようとした時に、現在の作業ディレクトリの変更と競合が発生
  • 同じファイルの同じ箇所が変更されている

解決方法:

# 解決手順1: 現在の変更も退避
$ git stash

# 解決手順2: 元のstashを適用
$ git stash apply stash@{1}

# 解決手順3: コンフリクトが発生した場合は手動で解決
$ git status
On branch main
Unmerged paths:
  (use "git add <file>..." to mark resolution)
    both modified:   src/components/Header.js

# 解決手順4: ファイルを編集してコンフリクトを解決
$ vim src/components/Header.js

# 解決手順5: 解決したらaddする
$ git add src/components/Header.js

# 解決手順6: 最初に退避した変更を適用
$ git stash pop

エラー2: stashが適用できない

エラー内容:

error: cannot apply to a dirty working tree, please stage your changes

原因:

  • 作業ディレクトリに未コミットの変更がある
  • インデックスに追加された変更がある

解決方法:

# 方法1: 現在の変更をコミット
$ git add .
$ git commit -m "WIP: 一時的なコミット"
$ git stash apply
$ git reset HEAD~  # 必要に応じてコミットを取り消し

# 方法2: 現在の変更も退避
$ git stash
$ git stash apply stash@{1}  # 目的のstashを適用
$ git stash apply  # 先ほど退避した変更を再適用

エラー3: 誤ってstashを削除してしまった

エラー内容:

$ git stash drop
Dropped refs/stash@{0} (abc1234...)
# あっ、間違えた!

原因:

  • git stash dropgit stash clearを誤って実行
  • 重要な変更が含まれていたstashを削除

解決方法:

# 解決手順1: 削除されたstashのハッシュを探す
$ git fsck --no-reflogs | grep commit
dangling commit abc1234567890abcdef1234567890abcdef12345
dangling commit def5678901234567890abcdef1234567890abcd

# 解決手順2: 各コミットの内容を確認
$ git show abc1234567890abcdef1234567890abcdef12345

# 解決手順3: 目的のstashが見つかったら復元
$ git stash apply abc1234567890abcdef1234567890abcdef12345

エラー4: インデックスの状態が復元されない

エラー内容:

$ git stash pop
# インデックスに追加していた変更が、追加されていない状態で復元される

原因:

  • デフォルトではstashはインデックスの状態を保持しない
  • git addした状態が失われる

解決方法:

# stash作成時に--indexオプションを使用
$ git stash --index

# または適用時に--indexオプションを使用
$ git stash apply --index

トラブル予防のチェックリスト

  • [ ] stash前に必ずgit statusで状態を確認
  • [ ] 重要な変更には必ず意味のあるメッセージを付ける
  • [ ] 定期的にgit stash listで不要なstashを整理
  • [ ] 複数人で作業する場合はstashではなくブランチを使用
  • [ ] 長期間放置されるような変更はコミットを検討

💡 ベストプラクティス

1. 意味のあるメッセージを付ける

推奨される方法:

# Good ✅
git stash push -m "feat: ユーザー認証機能の実装途中(バリデーション部分)"
git stash push -m "fix: API エラーハンドリングの改善(レスポンス形式統一前)"

避けるべき方法:

# Bad ❌
git stash
git stash push -m "WIP"
git stash push -m "一時保存"

理由: 複数のstashがある場合、メッセージがないと内容を把握するのが困難。後で見返した時に何の作業だったか分からなくなる。

2. チーム開発での活用法

  • ルール1: stashは個人の作業管理ツールとして使用し、共有が必要な場合はブランチを作成
  • ルール2: 1日以上放置されるような変更はstashではなくWIPコミットを推奨
  • ルール3: ペアプログラミングやモブプログラミング時は、ドライバー交代時にstashを活用

3. 自動化とエイリアス設定

# ~/.gitconfig に追加する便利なエイリアス
[alias]
    # stash関連のエイリアス
    s = stash
    sp = stash pop
    sl = stash list
    ss = stash save
    sa = stash apply
    sd = stash drop
    
    # メッセージ付きstash
    sm = "!f() { git stash push -m \"$1\"; }; f"
    
    # stashの内容を確認してから適用
    sshow = "!f() { git stash show -p stash@{${1:-0}}; }; f"
    
# 使用例
$ git sm "認証機能の実装途中"
$ git sl
$ git sshow 0  # stash@{0}の内容を表示
$ git sa stash@{0}

4. stashブランチの活用

# stashから新しいブランチを作成
$ git stash branch feature/new-feature

# これは以下の操作と同等
$ git checkout -b feature/new-feature
$ git stash pop

メリット:

  • stashの内容を安全にブランチ化できる
  • コンフリクトのリスクを減らせる
  • チームメンバーと共有しやすくなる

📊 コマンドオプション完全リファレンス

主要オプション詳細

オプション一覧を展開

オプション長い形式説明使用例
-u--include-untracked未追跡ファイルも含めるgit stash -u
-a--all無視ファイルも含めるgit stash -a
-m--message説明メッセージを追加git stash -m "説明"
-p--patch対話的に選択git stash -p
-k--keep-indexインデックスを保持git stash -k
-q--quiet静かに実行git stash -q
--indexインデックスの状態も復元git stash apply --index

サブコマンド一覧:

サブコマンド説明使用例
push新しいstashを作成(デフォルト)git stash push
popstashを適用して削除git stash pop
applystashを適用(削除しない)git stash apply
liststashの一覧表示git stash list
showstashの内容表示git stash show
dropstashを削除git stash drop
clearすべてのstashを削除git stash clear
branchstashから新規ブランチ作成git stash branch <name>

オプションの組み合わせパターン

目的コマンド例効果
完全な退避git stash -u -m "説明"未追跡ファイルも含めてメッセージ付きで退避
選択的退避git stash -p -k対話的に選択し、インデックスは保持
確認してから適用git stash show -p && git stash pop内容を確認してから適用
安全な適用git stash apply --indexインデックスの状態も含めて適用

🎯 実践演習

演習1: 基本操作の練習

課題: 複数のファイルを変更し、一部だけをstashして、別の作業を行った後に復元する
解答を見る

# 準備
$ echo "変更1" >> file1.txt
$ echo "変更2" >> file2.txt
$ echo "新規ファイル" > file3.txt

# 解答例
$ git add file1.txt  # file1.txtだけをインデックスに追加
$ git stash -k -m "file2.txtとfile3.txtの変更を退避"  # インデックスを保持してstash
$ git commit -m "file1.txtを更新"  # file1.txtをコミット
$ git stash pop  # 退避した変更を復元

解説:

  • -kオプションでインデックスの内容(file1.txt)はstashされない
  • これにより、一部の変更だけを選択的に退避できる
  • 実務では、関連性の低い変更を分離する際に有用

演習2: コンフリクト解決

課題: stash適用時にコンフリクトが発生した場合の対処
解答を見る

# 準備(コンフリクトを意図的に発生させる)
$ echo "元の内容" > conflict.txt
$ git add conflict.txt
$ git commit -m "conflict.txtを追加"
$ echo "stashする変更" > conflict.txt
$ git stash -m "conflict.txtの変更"
$ echo "別の変更" > conflict.txt

# 解答例
$ git stash apply
Auto-merging conflict.txt
CONFLICT (content): Merge conflict in conflict.txt

$ cat conflict.txt
<<<<<<< Updated upstream
別の変更
=======
stashする変更
>>>>>>> Stashed changes

# コンフリクトマーカーを手動で編集
$ vim conflict.txt  # 適切な内容に修正

$ git add conflict.txt  # 解決済みとしてマーク
$ git status  # 状態確認

解説:

  • コンフリクトは通常のマージと同じ方法で解決
  • 解決後は必ずgit addでマークする
  • 複雑な場合は、一度現在の変更もstashしてから対処する方法も有効

演習3: 高度なstash管理

課題: 複数のstashを作成し、特定のstashだけを選んで適用する
解答を見る

# 複数のstashを作成
$ echo "機能A" > featureA.txt
$ git stash push -m "機能A: 初期実装"

$ echo "機能B" > featureB.txt  
$ git stash push -m "機能B: UI部分"

$ echo "バグ修正" > bugfix.txt
$ git stash push -m "緊急: バグ修正"

# stashリストを確認
$ git stash list
stash@{0}: On main: 緊急: バグ修正
stash@{1}: On main: 機能B: UI部分
stash@{2}: On main: 機能A: 初期実装

# 特定のstashの詳細を確認
$ git stash show -p stash@{2}

# 機能Aのstashだけを適用(削除しない)
$ git stash apply stash@{2}

# 不要なstashを削除
$ git stash drop stash@{0}

# または番号を指定して複数削除
$ git stash drop stash@{1}
$ git stash drop stash@{0}

解説:

  • stashは新しいものからstash@{0}として番号付けされる
  • 特定のstashを操作する際は番号を指定
  • 定期的な整理でstashスタックをクリーンに保つ

🔗 関連リソース

公式ドキュメント

関連記事

次に学ぶべきコマンド

  1. git cherry-pick: 特定のコミットだけを取り込む
  2. git rebase -i: インタラクティブなリベースで履歴を整理
  3. git reflog: 操作履歴を確認して復元

📌 まとめ

この記事で学んだこと

  • ✅ git stashの基本的な使い方と動作原理
  • ✅ 実践的なオプションの活用方法
  • ✅ よくあるエラーの解決方法
  • ✅ チーム開発でのベストプラクティス
  • ✅ 高度なstash管理テクニック

重要なポイントの再確認

  1. 基本: stashは一時的な退避のためのツール、長期保存には向かない
  2. 応用: メッセージ付きstashと選択的stashで効率的な作業管理
  3. 注意: コンフリクトに備えて、適用前に内容確認を習慣化

実務での活用チェックリスト

  • [ ] 基本的な使い方をマスターした
  • [ ] よく使うオプションを覚えた
  • [ ] エラー対処法を理解した
  • [ ] チームでのルールを確認した
  • [ ] エイリアスを設定した

🚀 次のステップ

git stashをマスターしたら、次は他のGitコマンドとの組み合わせを学んでいきましょう。特にブランチ操作やマージ戦略と組み合わせることで、より柔軟な開発フローを構築できます。

実際のプロジェクトで積極的に使って、体で覚えていくことが上達への近道です。困ったときはこの記事に戻って、トラブルシューティングセクションを参照してください。

Happy Git Life! 🎉

さらに深く学びたい方へ

この記事で紹介した技術をマスターするには、体系的な学習が重要です。独学で挫折しそうな方は、現役
エンジニアから直接学べるプログラミングスクールも検討してみてください。

現場で通用するスキルを身につけるなら

DMM WEBCAMPのカリキュラムは、実際の開発現場を想定したチーム開発も経験できます。ポートフォリオ制作
支援もあり、転職活動で差をつけられます。

未経験から4ヶ月でエンジニアとして活躍できるレベルまで成長可能です。

実務レベルのWeb開発スキルを習得するなら

RUNTEQは、1000時間の圧倒的学習量で、現場で即戦力となるWebエンジニアを育成します。Ruby on
Railsに特化し、実際のWebサービス開発を通じて実践力を養います。

卒業生の多くが自社開発企業への転職に成功している実績があります。

じっくり理解を深めたい方へ

この記事で紹介した内容を確実に身につけるには、分からない点をすぐに質問できる環境が重要です。CodeCa
mpなら、現役エンジニアとのマンツーマンレッスンで、あなたのペースで着実にスキルアップできます。

朝7時〜夜23時まで、365日受講可能なので、仕事や学業と両立しながら学習を進められます。

git stash完全解説

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次