日本語 ▾ トピック ▾ 最新バージョン ▾ 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 に保存されます。古いスタッシュは、このリファレンスのリフロッグに見つかり、通常のリフロッグ構文(例: 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>…​]

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

素早くスナップショットを作成するには、「push」を省略できます。このモードでは、タイプミスによるサブコマンドが不要なスタッシュエントリを作成するのを防ぐため、オプション以外の引数は許可されません。この2つの例外は、stash -pstash push -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 entry は、その名前(例: 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

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

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

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

create

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

store

git stash create を通じて作成された特定のスタッシュ(ぶら下がったマージコミット)をスタッシュリファレンスに保存し、スタッシュリフロッグを更新します。これはスクリプトに役立つことを意図しています。おそらく使用したいコマンドではありません。「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 とワーキングツリーの差分からスタッシュするハンクをインタラクティブに選択します。スタッシュエントリは、そのインデックスの状態がリポジトリのインデックスの状態と同じであり、そのワークツリーにはインタラクティブに選択した変更のみが含まれるように構築されます。選択された変更は、その後ワークツリーからロールバックされます。--patch モードの操作方法については、git-add[1] の「インタラクティブモード」セクションを参照してください。

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

-S
--staged

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

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

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

--pathspec-from-file=<file>

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

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

--pathspec-file-nul

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

--pathspec-from-file と共にのみ意味を持ちます。pathspec 要素は NUL 文字で区切られ、他のすべての文字はリテラルとして扱われます(改行と引用符を含む)。

-q
--quiet

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

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

--

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

曖昧さを解消するために pathspec をオプションから区切ります。

<pathspec>…​

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

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

詳細については、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