日本語 ▾ トピック ▾ 最新バージョン ▾ git-stash は 2.43.0 で最終更新

名前

git-stash - ダーティなワーキングディレクトリの変更を一時的に退避させる

書式

git stash list [<log-options>]
git stash show [-u | --include-untracked | --only-untracked] [<diff-options>] [<stash>]
git stash drop [-q | --quiet] [<stash>]
git stash pop [--index] [-q | --quiet] [<stash>]
git stash apply [--index] [-q | --quiet] [<stash>]
git stash branch <branchname> [<stash>]
git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
	     [-u | --include-untracked] [-a | --all] [(-m | --message) <message>]
	     [--pathspec-from-file=<file> [--pathspec-file-nul]]
	     [--] [<pathspec>…​]]
git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
	     [-u | --include-untracked] [-a | --all] [<message>]
git stash clear
git stash create [<message>]
git stash store [(-m | --message) <message>] [-q | --quiet] <commit>

説明

git stashは、ワーキングディレクトリとインデックスの現在の状態を記録しつつ、クリーンなワーキングディレクトリに戻りたい場合に使用します。このコマンドはローカルの変更を退避させ、ワーキングディレクトリをHEADコミットの状態に戻します。

このコマンドで退避された変更は、git stash listで一覧表示し、git stash showで確認し、git stash applyで(場合によっては異なるコミットの上に)復元できます。引数なしでgit stashを呼び出すことは、git stash pushと同じです。スタッシュはデフォルトで「WIP on branchname …​」として一覧表示されますが、スタッシュを作成する際にコマンドラインでより詳細なメッセージを指定できます。

作成した最新のスタッシュはrefs/stashに保存されます。古いスタッシュはこのリファレンスのreflogに見つけることができ、通常のreflog構文(例:stash@{0}は最も最近作成されたスタッシュ、stash@{1}はその前のもの、stash@{2.hours.ago}も可能です)を使用して名前を付けることができます。スタッシュはスタッシュインデックスのみを指定することでも参照できます(例:整数nstash@{n}と同等です)。

コマンド

push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [(-m|--message) <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>…​]

ローカルの変更を新しいスタッシュエントリに保存し、それらをHEAD(ワーキングツリーとインデックス)の状態にロールバックします。<message>部分はオプションで、スタッシュされた状態とともに説明を提供します。

スナップショットを素早く作成するには、「push」を省略できます。このモードでは、誤って入力されたサブコマンドが意図しないスタッシュエントリを作成するのを防ぐため、オプション以外の引数は許可されません。この例外は2つあります。stash push -pのエイリアスとして機能するstash -pと、あいまいさを解消するための二重ハイフン--の後に許可されるpathspec要素です。

save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]

このオプションはgit stash pushの使用が推奨されるため非推奨となりました。「stash push」とは異なり、pathspecを取ることができません。代わりに、オプション以外のすべての引数は連結されてスタッシュメッセージを形成します。

list [<log-options>]

現在持っているスタッシュエントリを一覧表示します。各スタッシュエントリは、その名前(例:stash@{0}は最新のエントリ、stash@{1}はその前のものなど)、エントリが作成されたときに現在のブランチだったものの名前、およびエントリが基づいていたコミットの簡単な説明とともにリストされます。

stash@{0}: WIP on submit: 6ebd0e2... Update git-stash documentation
stash@{1}: On master: 9cc0589... Add git-stash

このコマンドは、表示内容と方法を制御するために*git log*コマンドに適用可能なオプションを取ります。git-log[1]を参照してください。

show [-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>]

スタッシュエントリに記録された変更を、スタッシュされた内容とスタッシュエントリが最初に作成された時点のコミットとの間の差分として表示します。デフォルトでは、このコマンドはdiffstatを表示しますが、*git diff*が認識する任意のフォーマットを受け入れます(例:`git stash show -p stash@{1}`は2番目に新しいエントリをパッチ形式で表示します)。`<diff-option>`が提供されない場合、デフォルトの動作は`stash.showStat`および`stash.showPatch`設定変数によって決定されます。また、`stash.showIncludeUntracked`を使用して、`--include-untracked`がデフォルトで有効になるかどうかを設定できます。

pop [--index] [-q|--quiet] [<stash>]

スタッシュリストから単一のスタッシュ状態を削除し、現在のワーキングツリーの状態の上に適用します。つまり、git stash pushの逆操作を実行します。ワーキングディレクトリはインデックスと一致している必要があります。

状態の適用は競合により失敗する可能性があります。この場合、スタッシュリストからは削除されません。手動で競合を解決し、その後手動でgit stash dropを呼び出す必要があります。

apply [--index] [-q|--quiet] [<stash>]

popと同様ですが、スタッシュリストから状態を削除しません。popとは異なり、<stash>stash pushまたはstash createによって作成されたコミットのように見える任意のコミットであることができます。

branch <branchname> [<stash>]

<stash>が最初に作成されたコミットから始まる<branchname>という名前の新しいブランチを作成してチェックアウトし、<stash>に記録された変更を新しいワーキングツリーとインデックスに適用します。それが成功し、<stash>stash@{<revision>}形式のリファレンスである場合、<stash>を削除します。

これは、git stash pushを実行したブランチが十分に変わってしまい、競合のためにgit stash applyが失敗する場合に便利です。スタッシュエントリはgit stashが実行された時点のHEADだったコミットの上に適用されるため、元のスタッシュされた状態を競合なしで復元します。

clear

すべてのスタッシュエントリを削除します。これらのエントリはその後、パージの対象となり、回復が不可能になる可能性があることに注意してください(可能な戦略については下記の*例*を参照)。

drop [-q|--quiet] [<stash>]

スタッシュエントリのリストから単一のスタッシュエントリを削除します。

create

スタッシュエントリ(通常のコミットオブジェクト)を作成し、そのオブジェクト名をrefネームスペースのどこにも保存せずに返します。これはスクリプトに役立つことを意図しています。おそらくあなたが使用したいコマンドではありません。「push」を上記で参照してください。

store

*git stash create*で作成された指定されたスタッシュ(これはぶら下がっているマージコミットです)をスタッシュrefに保存し、スタッシュreflogを更新します。これはスクリプトに役立つことを意図しています。おそらくあなたが使用したいコマンドではありません。「push」を上記で参照してください。

オプション

-a
--all

このオプションはpushコマンドとsaveコマンドにのみ有効です。

すべての無視されたファイルと追跡されていないファイルもスタッシュされ、その後git cleanでクリーンアップされます。

-u
--include-untracked
--no-include-untracked

pushおよびsaveコマンドと共に使用すると、すべての追跡されていないファイルもスタッシュされ、その後git cleanでクリーンアップされます。

showコマンドと共に使用すると、スタッシュエントリ内の追跡されていないファイルを差分の一部として表示します。

--only-untracked

このオプションはshowコマンドにのみ有効です。

スタッシュエントリ内の追跡されていないファイルのみを差分の一部として表示します。

--index

このオプションはpopコマンドとapplyコマンドにのみ有効です。

ワーキングツリーの変更だけでなく、インデックスの変更も復元しようとします。ただし、競合がある場合(競合はインデックスに保存されるため、元の変更をそのまま適用できなくなります)は失敗する可能性があります。

-k
--keep-index
--no-keep-index

このオプションはpushコマンドとsaveコマンドにのみ有効です。

すでにインデックスに追加されたすべての変更はそのまま残されます。

-p
--patch

このオプションはpushコマンドとsaveコマンドにのみ有効です。

HEADとワーキングツリー間の差分からスタッシュするハンクを対話的に選択します。スタッシュエントリは、そのインデックスの状態がリポジトリのインデックスの状態と同じであり、そのワークツリーには対話的に選択した変更のみが含まれるように構築されます。選択された変更は、その後ワークツリーからロールバックされます。git-add[1]の「インタラクティブモード」セクションを参照して、`--patch`モードの操作方法を学んでください。

--patchオプションは--keep-indexを意味します。これをオーバーライドするには--no-keep-indexを使用できます。

-S
--staged

このオプションはpushコマンドとsaveコマンドにのみ有効です。

現在ステージされている変更のみをスタッシュします。これは基本的な`git commit`に似ていますが、状態が現在のブランチではなくスタッシュにコミットされる点が異なります。

--patchオプションはこのオプションよりも優先されます。

--pathspec-from-file=<file>

このオプションはpushコマンドにのみ有効です。

パススペックはコマンドライン引数の代わりに<file>で渡されます。<file>が正確に-の場合、標準入力が使用されます。パススペック要素はLFまたはCR/LFで区切られます。パススペック要素は設定変数core.quotePathで説明されているように引用符で囲むことができます(git-config[1]を参照)。また、--pathspec-file-nulとグローバルの--literal-pathspecsも参照してください。

--pathspec-file-nul

このオプションはpushコマンドにのみ有効です。

--pathspec-from-fileと組み合わせてのみ意味があります。パススペック要素はNULL文字で区切られ、他のすべての文字はリテラルとして扱われます(改行や引用符を含む)。

-q
--quiet

このオプションはapplydroppoppushsavestoreコマンドにのみ有効です。

静かに、フィードバックメッセージを抑制します。

--

このオプションはpushコマンドにのみ有効です。

あいまいさを解消するために、pathspecとオプションを区切ります。

<pathspec>…​

このオプションはpushコマンドにのみ有効です。

新しいスタッシュエントリは、パススペックに一致するファイルのみの変更された状態を記録します。これらのファイルのインデックスエントリとワーキングツリーファイルもHEADの状態にロールバックされ、パススペックに一致しないファイルはそのまま残されます。

詳細については、gitglossary[7]の*pathspec*エントリを参照してください。

<stash>

このオプションはapplybranchdroppopshowコマンドにのみ有効です。

stash@{<revision>}形式のリファレンスです。<stash>が指定されない場合、最新のスタッシュ(すなわちstash@{0})が仮定されます。

解説

スタッシュエントリは、ワーキングディレクトリの状態を記録するツリーを持ち、その最初の親がエントリ作成時のHEADコミットであるコミットとして表現されます。2番目の親のツリーは、エントリ作成時のインデックスの状態を記録し、HEADコミットの子となります。祖先グラフは次のようになります:

       .----W
      /    /
-----H----I

ここでHHEADコミット、Iはインデックスの状態を記録するコミット、Wはワーキングツリーの状態を記録するコミットです。

ダーティツリーへのプル

作業の途中で、進行中の作業に関連する可能性のある上流の変更があることを知ることがあります。ローカルの変更が上流の変更と競合しない場合、単純なgit pullで先に進むことができます。

しかし、ローカルの変更が上流の変更と競合し、git pullが変更の書き換えを拒否する場合があります。そのような場合、次のように変更をスタッシュし、プルを実行してから、スタッシュを解除することができます。

$ git pull
 ...
file foobar not up to date, cannot merge.
$ git stash
$ git pull
$ git stash pop
中断されたワークフロー

作業の途中で、上司が来て何かをすぐに修正するよう要求することがあります。従来、変更を一時的に保存するために一時ブランチにコミットを作成し、緊急修正を行うために元のブランチに戻るでしょう。次のように:

# ... hack hack hack ...
$ git switch -c my_wip
$ git commit -a -m "WIP"
$ git switch master
$ edit emergency fix
$ git commit -a -m "Fix in a hurry"
$ git switch my_wip
$ git reset --soft HEAD^
# ... continue hacking ...

上記の操作を*git stash*を使って簡素化できます。次のように:

# ... hack hack hack ...
$ git stash
$ edit emergency fix
$ git commit -a -m "Fix in a hurry"
$ git stash pop
# ... continue hacking ...
部分的なコミットのテスト

ワーキングツリーの変更から2つ以上のコミットを作成したい場合、そしてコミットする前に各変更をテストしたい場合に、git stash push --keep-indexを使用できます。

# ... hack hack hack ...
$ git add --patch foo            # add just first part to the index
$ git stash push --keep-index    # save all other changes to the stash
$ edit/build/test first part
$ git commit -m 'First part'     # commit fully tested change
$ git stash pop                  # prepare to work on all other changes
# ... repeat above five steps until one commit remains ...
$ edit/build/test remaining parts
$ git commit foo -m 'Remaining parts'
将来の使用のために無関係な変更を保存する

大規模な変更の途中で、修正を忘れたくない無関係な問題を見つけた場合、その変更を実行し、ステージし、git stash push --stagedを使用して将来のためにスタッシュに保存できます。これはステージされた変更をコミットするのと似ていますが、コミットが現在のブランチではなくスタッシュに終わる点が異なります。

# ... hack hack hack ...
$ git add --patch foo           # add unrelated changes to the index
$ git stash push --staged       # save these changes to the stash
# ... hack hack hack, finish current changes ...
$ git commit -m 'Massive'       # commit fully tested changes
$ git switch fixup-branch       # switch to another branch
$ git stash pop                 # to finish work on the saved changes
誤ってクリア/削除されたスタッシュエントリの回復

誤ってスタッシュエントリを削除またはクリアした場合、通常の安全メカニズムでは回復できません。しかし、以下の呪文を試して、リポジトリにまだ存在するが、もはや到達できないスタッシュエントリのリストを取得できます。

git fsck --unreachable |
grep commit | cut -d\  -f3 |
xargs git log --merges --no-walk --grep=WIP

設定

このセクションのこの行より下のすべての内容は、git-config[1]ドキュメントから選択的に含まれています。内容はそこにあるものと同じです。

stash.showIncludeUntracked

これがtrueに設定されている場合、git stash showコマンドはスタッシュエントリの追跡されていないファイルを表示します。デフォルトはfalseです。git-stash[1]の*show*コマンドの説明を参照してください。

stash.showPatch

これがtrueに設定されている場合、オプションなしのgit stash showコマンドはスタッシュエントリをパッチ形式で表示します。デフォルトはfalseです。git-stash[1]の*show*コマンドの説明を参照してください。

stash.showStat

これがtrueに設定されている場合、オプションなしのgit stash showコマンドはスタッシュエントリのdiffstatを表示します。デフォルトはtrueです。git-stash[1]の*show*コマンドの説明を参照してください。

GIT

git[1]スイートの一部

scroll-to-top