複数のブランチを跨いで業務を行う際、開発中の実装中に緊急の修正対応が発生することは珍しくありません。このような状況において、現在の作業状況を一時保留し、優先度の高いタスクへ移動するための標準的な手法として git stash が有効です。
使用シナリオの定義
例えば、新機能の実装が完了していない開発用ブランチにおいて、メインブランチに重大な不具合が見つかった場合を想定します。この際、開発中のコードを変更せず、まず主要なバグフィックスを完了させる必要があります。git stash を用いることで、未コミットのローカル変更を一時保存し、クリーンな状態からバグ修正に対応できるようになります。
実践デモ
まずはファイル操作を簡略化して、基本的なフローを確認します。例として、プロジェクトルートに config_data.json という設定ファイルを用意しているものとします。
$ pwd
/home/user/project
$ ls -l
-rw-r--r-- config_data.json
新規機能を開発するために、ベースブランチから新しいブランチを作成し、切り替えます。
git branch feat-user-profile
git checkout feat-user-profile
Switched to branch 'feat-user-profile'
このブランチ内で、ユーザープロファイル関連の設定を追加します。
$ echo "new_profile_feature=true" >> config_data.json
ここで、本番環境の運用ブランチ(主に main とします)で緊急修正が必要になったと仮定します。現在の作業ファイルを退避させます。
git stash save "Profile feature changes in progress"
Saved working directory and index state On feat-user-profile: initial commit
ステータスを確認すると、先ほどの変更が消去され、コミット前の状態に戻っています。
cat config_data.json
# (内容:メインブランチのもののみ表示)
次に、修正が必要な対象ブランチへ切り替えてバグ修正を行います。
git checkout main
git merge --no-edit feat-user-profile # (必要に応じて主分岐を最新にする)
vim config_data.json # バグ修正を行う
git add config_data.json
git commit -m "Hotfix: Critical security patch"
git push origin main
修正完了後、再び開発ブランチへ戻り、一時保存していた変更を取り出します。
git checkout feat-user-profile
スタッシュリストの復元方法
保存された変更は、リストとして保持されます。利用可能な復元手段は主に 2 つあります。
パターン A: git stash apply
リスト内のエントリを残したままワーキングディレクトリに反映する場合です。同じコードを再利用したり、別のスタッシュと併用したい場合に適しています。
git stash apply
On branch feat-user-profile
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: config_data.json
git stash list を実行すると、その内容は依然として存在していることを確認できます。
パターン B: git stash pop
復元と同時に、内部リストから当該エントリを削除する操作です。処理を一つ終わらせて整理したい場合はこちらが便利です。
git stash pop
On branch feat-user-profile
Changes to be committed:
new file: config_data.json
Dropped refs/stash@{0}...
もし既にブランチ間で差分が生じている場合、マージ競合が発生することがあります。その際は手動での解決が必要です。
競合の解消例:
Auto-merging config_data.json Both modified: config_data.json
vim config_data.json
# 競合箇所を解決
git add .
解決後は通常通り進行します。不要になったスタッシュ情報は、以下のコマンドで永続的に削除可能です。
git stash drop
既コミット済みデータの扱いはできない
注意点として、git stash で扱えるのは「ワーキングツリーおよびステージング領域の状態」のみです。すでにコミットされている履歴データは対象外となります。もし開発ブランチ上で数回のコミットを行ってしまい、そこから遡ってメインブランチの修正だけを適用する必要がある場合は、この手順では不可能です。そのようなケースにおいては、各コミット単位で特定の変更を転記する git cherry-pick のアプローチが必要となります。