git stashで一部の変更だけ退避したい|特定のファイルだけ一旦よけてみる

こんにちは、さるまりんです。

Gitを使って作業していると、

「この変更、まだcommitできないな」

ということがあります。

そんなときに使えるのが、

git stash

です。

変更した内容を一旦よけておいて、あとから戻すことができます。

でも、

git stash

をそのまま使うと、変更しているものをまとめて退避することになります。

そうではなく、

このファイルだけ一旦よけたい。

ということもあります。

今回は、git stash で特定のファイルだけを退避する方法を見ていきます。

まずは普通のgit stash

例えば、いくつかのファイルを変更しているとします。

src/User.php
src/Order.php
README.md

ここで、

git status

を見ると、

modified: src/User.php
modified: src/Order.php
modified: README.md

のようになっているとします。

この状態で、

git stash

を実行すると、変更している内容を一旦stashに退避できます。

便利ですね。

ただ今回は、

src/User.php

だけを一旦よけたいとします。

Order.php と README.md の変更は、そのまま残しておきたい。

そんなときには、ファイルを指定してstashします。

特定のファイルだけstashします

こんなふうに書けます。

git stash push -- src/User.php

これで、

src/User.php

の変更だけがstashされます。

もう一度、

git status

を確認すると、

src/Order.php
README.md

の変更は残っています。

つまり、

指定したファイルだけ一旦よける

ことができます。

-- の後ろに、stashしたいファイルを書くんですね。

複数のファイルも指定できます

一つだけではなく、複数のファイルを指定することもできます。

例えば、

git stash push -- src/User.php src/Order.php

とすれば、

src/User.php
src/Order.php

の変更をstashして、

README.md

の変更はそのまま残せます。

全部を一度によける必要はありません。

必要なものだけを選べます。

ワイルドカードを使ってまとめて指定することもできます

ファイルを一つずつ書く以外に、* を使ってまとめて指定することもできます。

例えば、

git stash push -- 'src/*.php'

とすると、src 以下でパターンに一致するPHPファイルをまとめてstashできます。

「このあたりのPHPファイルだけ一旦よけたい」

というときには便利そうですね。

ここでは、

*.php

の部分が、PHPファイルに一致するパターンになっています。

なお、

git stash push -- 'src/*.php'

のようにパターン全体をクォートしておくと、* をシェル側で先に展開させず、Gitのpathspecとして扱わせることができます。

Gitの通常のpathspecでは、* がディレクトリの区切りにも一致することがあります。そのため、'src/*.php' は src 直下だけではなく、その下のディレクトリにあるPHPファイルにも一致することがあります。

「このディレクトリ直下だけ」と思って使うと少し動きが違うことがあるので、そこだけ覚えておくと安心です。

stashしたものを確認します

stashした内容は、

git stash list

で確認できます。

例えば、

stash@{0}: WIP on main: ...

のように表示されます。

stashを何回か使っていると、

stash@{0}
stash@{1}
stash@{2}

のように増えていきます。

一番新しいものが、

stash@{0}

です。

どれだったかな?名前をつけておくとわかりやすい

stashが増えてくると、

「これ、何をよけたやつだっけ?」

となることがあります。

そんなときは、メッセージをつけておくとわかりやすいです。

git stash push -m "User.phpの変更" -- src/User.php

そして、

git stash list

を見ると、何のためにstashしたのかがわかりやすくなります。

少し長く置いておく可能性があるなら、名前をつけておくと安心です。

stashした変更を戻します

一番新しいstashを戻すなら、

git stash pop

です。

stashした変更がワークツリーに戻ってきます。

pop は、変更を戻したあと、そのstashを一覧から取り除きます。

一方、

git stash apply

というものもあります。

こちらも変更を戻しますが、stash自体は残ります。

つまり、

pop
→ 戻して、stashからも取り除く

apply
→ 戻すけれど、stashは残しておく

という違いがあります。

普段は pop で十分なことも多いですが、

「念のためstashを残しておきたい」

というときには、apply を使う方法もあります。

stashが複数ある場合は、例えば、

git stash pop 'stash@{1}'

のように、戻したいstashを指定することもできます。

stashの中身を見たいとき

戻す前に、

「何をstashしたんだっけ?」

と確認したいこともあります。

そんなときは、

git stash show

で確認できます。

もう少し詳しく差分を見たいなら、

git stash show -p

とすると、変更内容を見ることができます。

いきなり戻すのがちょっと不安なときに便利ですね。

新しく作ったファイルは少し注意

ここで一つ注意です。

通常の git stash は、Gitでまだ追跡されていない新しいファイルを、そのままではstashしません。

例えば、

new-file.txt

を新しく作ったけれど、まだ git add していない場合です。

そういうファイルもstashしたい場合には、

git stash push -u -- new-file.txt

のように、

-u

を使う方法があります。

-u は、

--include-untracked

の短い書き方です。

include-untracked、「追跡されていないものを含む」の意味です。

「ファイルを指定したのにstashされないな」

と思ったときは、そのファイルがまだGitに追跡されていないものではないか確認してみるといいかもしれません。

変更の一部分だけstashしたい場合もあります

今回は、

ファイル単位

でstashしました。

でも、

「同じファイルの中でも、この変更だけよけたい」

ということもあります。

そんなときには、

git stash -p

という方法もあります。

-p は変更箇所を見ながら、一つずつstashするかどうかを選べます。

これはまた少し違った使い方なので、別の機会にゆっくり見てみてもよさそうです。

僕自身、どんな動きをするのか興味津々です。

まとめ

今回は、特定のファイルだけを git stash する方法を見てみました。

一つのファイルなら、

git stash push -- src/User.php

複数なら、

git stash push -- src/User.php src/Order.php

パターンでまとめて指定するなら、

git stash push -- 'src/*.php'

と書けます。

stashしたものは、

git stash list

で確認できます。

戻すときは、

git stash pop

または、

git stash apply

です。

作業をしていると、

「全部をstashしたいわけじゃないんだよな」

ということがあります。

そんなときに、

git stash push -- ファイル名

を知っていると、必要な変更だけ一旦よけることができます。

Gitは、少しずつ便利な使い方を覚えていくと、

「こういうこともできるんだ」

というものが結構あります。

また一つずつ見ていきましょう。

読んでくださってありがとうございました。

それではまた!