「git stash -u」は危険なので、「git stash push -um」を使うべき

git stash -u は危険

去年は自社で「git stash -u」による大きな事故が2回も発生しました。

git stash -u(--include-untracked)は一見便利そうに見えますが、実務では事故の原因になりやすく、原則として使うべきではありません。

なぜ git stash -u は危険なのか

git stash -u は未追跡ファイル(Untracked files)も一緒に退避するコマンドです。

未追跡ファイルには以下のようなものが含まれがちです。

  • 一時的に作った検証用ファイル (consoleやダミーのコードを含むなど)
  • 誤って生成された不要ファイル (コマンドのミスや自動生成の一時ファイルなど)
  • OSやエディタの一時ファイル (macOSやVS Codeなど)

git stash -u を使うと、それらすべてがメッセージを付けずに無差別にstashに入るため、何を退避したのかわからない状態になりやすいです。

復元したら想定外のファイルが出現したり、競合が発生するなど、「stashした人にすら覚えていなければわからない状態」 を作る行為になります。

git stash push -um は安全

git stash push -um であれば git stash -u と違ってメッセージを残せるため、何のファイルを退避したのかわかりやすくなり安全です。

git stash push -um "API確認のための一時修正ファイル"

git stash push であれば次のように特定のパスのファイルだけ退避させることもできます。

git stash push -um "サンプル画像を退避" src/assets/

git stash save を使用している方も多いですが、git stash save だと前述のパスを指定した退避ができませんし、現在では非推奨となっているので使用しないほうが良いです。

save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] []
This option is deprecated in favour of git stash push. It differs from "stash push" in that it cannot take pathspecs, and any non-option arguments form the message.

必ず何が反映されるかを確認してから反映する

退避したファイルを単純に git stash pop で復元させてしまうケースをよく見かけます。

退避した内容を確実に覚えているファイルでなければ git stash list や git stash show -u で退避した内容を確認してから反映したほうが安全です。

$ git stash list
stash@{0}: On main: サンプル画像を退避

$ git stash show -u stash@{0}
 src/assets/sample.jpg        | Bin 0 -> 26147 bytes
 src/assets/foo.svg |   1 +
 2 files changed, 1 insertion(+)

$ git stash pop stash@{0}

ちなみにこれらのコマンドは少し長いので、Gitのエイリアスに登録しておくと入力が楽になります。

# エイリアスを登録する
git config --global alias.sp 'stash push -um'
git config --global alias.sl 'stash list'
git config --global alias.ss '!f() { git stash show -u stash@{$1}; }; f'
git config --global alias.sps '!f() { git stash pop stash@{$1}; }; f'
# git stash push -um "サンプル画像を退避" src/assets/
git sp "サンプル画像を退避" src/assets/

# git stash list
git sl

# git stash show -u stash@{0}
git ss 0

# git stash pop stash@{0}
git sps 0

ちなみにこのエイリアスを使用した場合は、git sp はメッセージを指定しないと退避できないので、メッセージを書き忘れることはありません。

$ git sp
error: switch `m' requires a value

さらに git sps は番号を指定しないと復元できないので、間違えて別の退避ファイルを反映させてしまうミスを減らせます。

$ git sps
error: stash@{} is not a valid reference

まとめ

git stash -u は未追跡ファイルまで無差別に退避してしまうため、何を退避したのかわからなくなりやすく、重大な事故の原因になりやすいコマンドです。

特にメッセージが残らない点は致命的で、復元時に想定外のファイルが混入したり、競合を引き起こすリスクがあります。

安全に運用するためには、必ずメッセージを付けられる git stash push -um を使用すること、必要に応じてパスを指定して退避することが重要です。