よくある話が、作業の途中で急に別のブランチに切り替えたくなる場面。
コミットするほどはまとまっていないが、そのままではブランチを切り替えられない。ところが、コミットせずに変更を一時的に退避できるのがgit stash。
この記事では、基本の使い方から、実務でつまずきやすい複数stashの管理方法までまとめた。

stashの基本:退避して、戻す
退避する:stash
作業中の変更を退避するには、次のコマンドを使う。
git stashワーキングツリーとステージの変更が退避され、直前のコミット状態に戻る。これで別のブランチへ自由に切り替えられる。
戻す:stash pop
作業を再開するときは、退避した内容を元に戻す。
git stash popこれだけで、コミットを汚さずに一時中断・再開ができる。
popとapplyの違い
退避した内容を戻すコマンドには、popのほかにapplyもある。
| コマンド | 戻したあとのstash | 使うタイミングの目安 |
|---|---|---|
| stash pop | 一覧から削除される | 普段の一時退避(そのまま使い切る) |
| stash apply | 一覧に残る | 同じ変更を複数のブランチに適用したいとき |
迷ったらpopで十分。applyは、同じ変更を別ブランチにも当てたい、といった特殊な場面だけ意識すればいい。
複数のstashを管理する
一覧を確認する:stash list
stashは何度でも積み重ねられる。何を退避したか分からなくなったら、一覧で確認する。
git stash list特定のstashを指定する
複数ある場合、単にpopやapplyだけを実行すると一番新しいものが対象になる。特定のstashを指定したいときは番号を渡す。
git stash pop stash@{2}メッセージを付けて退避する
意外と見落としがちだが、stashは積み重なるほど「どれが何だったか」が分かりにくくなる。退避するときにメッセージを付けておくと、あとで迷わない。
git stash push -m "検索機能の途中作業"一部のファイルだけ退避する
変更したファイルのうち、一部だけを退避したい場合は-p(--patch)オプションを使う。
git stash push -p変更のかたまり(hunk)ごとに、退避するかどうかを対話形式で選べる。1つのファイルに複数の作業が混ざってしまったときに使う。
stashをそのまま新しいブランチにする
退避した内容が、実は別ブランチとして進めるべき作業だった、というケースもある。その場合はstash branchが使える。
git stash branch new-feature stash@{0}新しいブランチを作成し、そこにstashの内容を復元してくれる。stashを適用する際にコンフリクトが起きそうな場合にも、退避元の状態を汚さず試せるので安心。
よくある質問
本文で触れきれなかった細かい疑問をQ&Aでまとめておきます。
stash popで戻すときにコンフリクトが起きたらどうすればいいですか?
通常のマージコンフリクトと同様に、該当ファイルを手動で解消してgit addします。このケースではpopが完了扱いにならずstash自体は一覧に残るため、解消後に不要であればgit stash dropで手動削除してください。
stashしたのに変更が退避されないファイルがあります。なぜですか?
新規追加した未追跡ファイル(Untracked files)は、デフォルトでは退避対象になりません。含めたい場合はgit stash -u(--include-untracked)を使ってください。
不要になったstashを削除するには?
特定の1件を消すならgit stash drop stash@{番号}、全部まとめて消すならgit stash clearを使います。clearは復元できないため、実行前に本当に不要か確認してください。
まとめ
基本はstashとstash popの2つで十分。管理に困ったらlistで確認し、複雑な場面ではメッセージ付き退避や-p、stash branchを使い分ければいい。

コメント