955

スタッシュチェンジセットをポップオフせずに、gitスタッシュから単一のファイルまたはファイルの差分を抽出することは可能ですか?

4

9 に答える 9

1373

git stashのマンページでは、(「ディスカッション」セクションの「オプション」の説明の直後に)次のように読むことができます。

stashは、ツリーが作業ディレクトリの状態を記録するコミットとして表され、その最初の親は、stashが作成されたときのHEADでのコミットです。

したがって、stash(たとえばstash@{0}、最初/最上位のstash)をマージコミットとして扱い、次を使用できます。

$ git diff stash@{0}^1 stash@{0} -- <filename>

説明:stash@{0}^1指定された隠し場所の最初の親を意味します。これは、上記の説明で述べたように、変更が隠されたコミットです。stash@{0}/はマージコミットであるため、この形式の「git diff」(2つのコミットを含む)を使用しrefs/stash、どの親に対して差分をとるかをgitに指示する必要があります。もっと謎めいた:

$ git diff stash@{0}^! -- <filename>

動作するはずです(構文の説明については、「範囲の指定」セクションのgit rev-parseのマンページを参照してください)。rev^!

同様に、git checkoutを使用して、スタッシュから1つのファイルをチェックアウトできます。

$ git checkout stash@{0} -- <filename>

または別のファイル名で保存するには:

$ git show stash@{0}:<full filename>  >  <newfile>

また

$ git show stash@{0}:./<relative filename> > <newfile>

(ここで、<full filename>は、プロジェクトの最上位ディレクトリを基準にしたファイルの絶対パス名であることに注意してください(例:relative to stash@{0}))。


stash@{0}シェルの拡張から保護する必要がある場合があります。つまり、"stash@{0}"またはを使用します'stash@{0}'

于 2009-07-09T18:21:11.110 に答える
60

git stash applyではなくを使用するgit stash popと、作業ツリーにスタッシュが適用されますが、スタッシュは保持されます。

これが完了すると、add/必要なcommitファイルを作成し、残りの変更をリセットできます。

于 2009-07-09T17:58:37.940 に答える
41

編集:cambunctiousの回答を参照してください。これは、現在の状態と比較するのではなく、隠し場所の変更のみを使用するため、基本的に私が現在好んでいるものです。これにより、操作が追加され、スタッシュが作成されてから行われた作業を元に戻す可能性がはるかに低くなります。

インタラクティブに行うには、最初に

git diff stash^! -- path/to/relevant/file/in/stash.ext perhaps/another/file.ext > my.patch

...次に、パッチファイルをテキストエディタで開き、必要に応じて変更してから、

git apply < my.patch

cambunctiousの答えは、1つのコマンドを別のコマンドに直接パイプすることによって対話性をバイパスします。これは、隠し場所からすべての変更が必要であることがわかっている場合は問題ありません。を編集しstash^!て、必要な累積変更を含む任意のコミット範囲にすることができます(ただし、最初にdiffの出力を確認してください)。

patch / diffの適用が失敗した場合は、可能なすべての変更を行う最後のコマンドを変更し、解決できない競合があるファイルgit apply --rejectを残すことができます。ファイルは、次.rejのようにを使用して適用できます。.rejwiggle

wiggle --replace path/to/relevant/file/in/stash.ext{,.rej}

これにより、競合が解決されるか、マージから取得する競合マーカーが提供されます。

ディストリビューションにがない場合はwiggle、ビルドするだけです。

cd /usr/local/src/
git clone git://git.neil.brown.name/wiggle
cd wiggle/
git checkout v1.3
make install

以前の解決策:スタッシュを含む任意のブランチから変更を取得する簡単な方法があります。

$ git checkout --patch stash@{0} path/to/file

多くの部分にパッチを適用する場合は、ファイル仕様を省略できます。または、パッチ(パスではなく)を省略して、すべての変更を1つのファイルに取得します。複数ある場合は0、のスタッシュ番号に置き換えてください。git stash listこれはのようなものであり、ブランチ間のすべての違いdiffを適用することを提案していることに注意してください。単一のコミット/スタッシュからのみ変更を取得するには、を参照してください。git cherry-pick --no-commit

于 2017-06-26T03:20:58.110 に答える
35
$ git checkout stash@{0} -- <filename>

ノート:

  1. 「-」とファイル名パラメータの後に必ずスペースを入れてください

  2. zero(0)を特定のスタッシュ番号に置き換えます。スタッシュリストを取得するには、次を使用します。

    git stash list
    

JakubNarębskiの回答に基づく-短いバージョン

于 2017-09-08T05:53:17.820 に答える
33

短い答え

ファイル全体を表示するには:git show stash@{0}:<filename>

差分を表示するには:git diff stash@{0}^1 stash@{0} -- <filename>

于 2015-12-22T13:05:13.137 に答える
14

以下を使用して、スタッシュ内のファイルへの変更を作業ツリーに適用します。

git diff stash^! -- <filename> | git apply

git checkoutスタッシュを作成してからファイルに加えた変更が失われることはないため、これは一般的に使用するよりも優れています。

于 2019-12-08T00:03:57.963 に答える
11

git show stash@{0}「 」(またはスタッシュの数に関係なく、「git stashlist」を参照)を使用して、スタッシュの差分を取得できます。単一のファイルの差分のセクションを抽出するのは簡単です。

于 2009-07-09T17:42:45.990 に答える
5

理解するのに最も簡単な概念は、最善ではないかもしれませんが、3つのファイルを変更し、1つのファイルを隠したいというものです。

git stashそれらをすべて隠しておく場合は、git stash applyそれらを元に戻しgit checkout f.c、問題のファイルで効果的にリセットします。

そのファイルのスタッシュを解除したい場合は、スタッシュスタックからの差分をクリアしないという事実を利用して、を実行してgit reset --hardから再度実行します。git stash applygit stash apply

于 2010-07-19T15:36:40.927 に答える
1

隠しファイルを現在のバージョンとマージする必要がある場合は、diffを使用して以前の方法を使用してください。それ以外の場合はgit pop、それらをアンスタッシュするgit add fileWantToKeepため、ファイルをステージングするため、およびgit stash save --keep-indexステージ上にあるものを除くすべてをスタッシュするためにを使用する可能性があります。この方法と以前の方法との違いは、ファイルをstashから「ポップ」することです。前の答えはそれを維持するgit checkout stash@{0} -- <filename>ので、あなたのニーズに応じて進みます。

于 2017-10-26T12:59:41.557 に答える