Git
英語 ▾ トピック ▾ 最新バージョン ▾ 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 *ブランチ名* …​" としてリストされますが、作成時にコマンドラインでより詳細なメッセージを指定することができます。

最後に作成したスタッシュは 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* で知られている任意の形式を受け入れます(例:2 番目に新しいエントリをパッチ形式で表示するには、git stash show -p stash@{1})。<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 コマンドでのみ有効です。

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

--index

このオプションは、pop および apply コマンドでのみ有効です。

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

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

このオプションは、push および save コマンドに対してのみ有効です。

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

-p
--patch

このオプションは、push および save コマンドに対してのみ有効です。

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

--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 と一緒にのみ意味があります。パス指定の要素は NUL 文字で区切られ、他のすべての文字は(改行や引用符を含め)文字通りに解釈されます。

-q
--quiet

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

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

--

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

あいまいさを解消するために、パス指定をオプションから分離します。

<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