Git stash:「ダーティな作業ツリーには適用できません。変更をステージングしてください」


133

以前に隠した変更を適用しgit stash popてメッセージを取得しようとしています:

Cannot apply to a dirty working tree, please stage your changes

それに対処する方法について何か提案はありますか?

回答:


196

stashされた変更をダーティ作業コピーに適用する必要がある場合、たとえばstashから複数の変更セットをポップする場合は、以下を使用します。

$ git stash show -p | git apply -3 && git stash drop

基本的には

  1. パッチを作成します
  2. 適用コマンドへのパイプ
  3. 競合がある場合は、3者間マージで解決する必要があります。
  4. 適用(またはマージ)が成功した場合、適用されたstashアイテムをドロップします...

上記のワンライナーのように正確に動作する-f(強制)オプションがないのはなぜですか?git stash pop

当面は、この1行をgitエイリアスとして追加することをお勧めします。

$ git config --global --replace-all alias.unstash \
   '!git stash show -p | git apply -3 && git stash drop'
$ git unstash

-33ウェイマージを介して直接競合を解決できるようにするパラメーターを指摘してくれた@SamHaslerに感謝します。


とはgit stash show -p | git apply違うgit stash apply
Factor Mystic

1
Jo Factor git stash applyは、ダーティな作業コピーがある場合、隠された変更を適用しません。したがってgit stash show -p | git apply、ある種の強制スタッシュが適用されることがわかります。
muhqu

1
助けにはならないが、助けにはなる:git reset HEADとその後の変更を元に戻す。
ロジャーエイリアン

4
いずれかのファイルで「エラー:パッチが失敗しました...パッチが適用されません」と表示されます。マージの競合が発生したことを願っています。
Aleksandr Dubinsky 2014年

1
この解決策は私にはうまくいきませんでした、error: <file> does not match index修正されたすべてのファイルで失敗しました。ただし、別のソリューションが機能しました。
シルベノン2017年

57

私はこのようにします:

git add -A
git stash apply

次に(オプション):

git reset

2
+1!これは、パッチの生成やコミットの修正を伴う他のソリューションよりも簡単で、変更が適切にマージされるまで、ローカルの変更を適用されたstashの変更から安全に分離します。
peterflynn 2013

「...は既に存在し、チェックアウトは行われていません...追跡されていないファイルをスタッシュから復元できませんでした」
Aleksandr Dubinsky

2
私はを使用しましたがgit add -u-A追跡されていないファイルを追加しない点が異なります。
Brad Cupit、2015年

9

これは、必要なスタッシュをパッチファイルとしてエクスポートして手動で適用することにより、現在の変更をスタッシュすることなく実行できます。

たとえば、stash @ {0}をダーティツリーに適用するとします。

  1. stash @ {0}をパッチとしてエクスポートします。

    git stash show -p stash @ {0}> Stash0.patch

  2. 変更を手動で適用します。

    git apply Stash0.patch

2番目のステップが失敗した場合は、Stash0.patchファイルを編集してエラーを修正してから、もう一度git applyを実行する必要があります。


これは、私がdirでリファクタリングを行った(削除して、その名前のシンボリックリンクを作成した)場合に実用的で実行可能です。Gitは、作業コピーの変更内容を特定できませんでした。
yclian

1
これはうまくいきました。私の作業ツリーがクリーンであると確信しているのに、スタッシュを適用できませんでした。
Shiki、

はい、バイナリファイルに関する行を削除する必要がありました。
ドリアン

8

git resetを使用して作業ディレクトリをクリーンアップするか、変更をコミットするか、現在の変更を隠したい場合は、次のことを試してください。

$ git stash save「現在の変更の説明」
$ git stash pop stash @ {1}

これにより、現在の変更が隠され、スタッシュスタックから2番目のスタッシュがポップされます。


5
しかし、この男は2つの隠し場所を適用したいと考えています!
Elazar Leibovich

@エラザーあなたは質問を読んでいます。OPは、以前の隠し場所を適用したいだけです。現在の変更を保持することが正しい場合、ソリューションを繰り返すことができます:ポップ、コミット、繰り返し。
ウィリアムパーセル2011

私は彼が両方ともコミットされていないことを望みます。しかし、もう一度、彼はそれらを2回コミットし、それらを1つのコミットにつぶすことができます。
Elazar Leibovich

「...は既に存在し、チェックアウトは行われていません...追跡されていないファイルをスタッシュから復元できませんでした」というエラーが表示される
Aleksandr Dubinsky

6

Mathiasのソリューションは、間違いなくgit stash pop --forceに最も近いものです(実際には、Git開発者の皆さん、このオプションをすでに入手しましょう!)

ただし、gitコマンドのみを使用して同じことをしたい場合は、次のことができます。

  1. git commit -a -m "Fixme"
  2. git stash pop
  3. git commit -a --amend
  4. git reset HEAD〜

言い換えると、現在の変更をコミット(プッシュしない)します。ワークスペースがきれいになったので、隠しておいてください。ここで、以前のコミットの修正としてstashの変更をコミットします。これで、両方の変更セットが1つのコミット( "Fixme")に結合されました。チェックアウトをリセットして(--soft NOT --hardなので、実際には何も失われません)、チェックアウトを「1つ前のコミット」にリセットすると、両方の変更セットが完全にコミットされなくなります。

**編集* *

私はそれが実際にはさらに簡単であることを認識しました。ステップ3は完全にスキップできるので...

  1. git commit -a -m "Fixme"
  2. git stash pop
  3. git reset HEAD〜

(現在の変更をコミットし、隠しておいた変更をポップし、その最初のコミットをリセットして、両方の変更セットをコミットされていない状態で結合します。)


4

私が今日したように、このような状況に陥った場合、これらの答えはどれも実際には機能しません。何回git reset --hardやっても、どこにも行きませんでした。私の答え(決して公式ではなかった):

  1. スタッシュのハッシュの使用法を理解する git reflog --all
  2. そのハッシュを興味のあるブランチとマージします

1
ヤーありがとうございます。あなたが説明したのと同じ問題で、Gitが私のローカルリポジトリで奇妙に振る舞ったことに私は苛立ちました。
yclian

4

また、Mathias Leppichのソリューション適切に機能することがわかったので、グローバル.gitconfigにそのエイリアスを追加しました

[alias]
        apply-stash-to-dirty-working-tree = !git stash show -p | git apply && git stash drop

今すぐ入力できます

git apply-stash-to-dirty-working-tree

それは私にとってはとてもうまくいきます。

(あなたのマイレージは、この長いエイリアス名によって異なる場合があります。しかし、bashの完了に伴う冗長性のほうが好きです。)


3

「ダーティ」ツリーにスタッシュを適用して、行ったgit add変更をステージングして、ツリーをクリーンアップできます。次にgit stash pop、隠しておいた変更を適用できます。問題ありません。


2

変更されているがコミットされていないファイルがあります。どちらか:

git reset --hard HEAD (to bring everything back to HEAD)

または、変更を保存する場合:

git checkout -b new_branch
git add ...
git commit
git checkout -b old_branch
git stash pop

1
@MikeCooper-コミットする前に、追加したいものは何でも追加するつもりだったと思います。
sscirrus

0

私は同じ問題を抱えていましたが、gitには変更されたファイルはありませんでした。あちこちにあるindex.lockファイルがあることがわかりました。削除すると問題は解決しました。


0

これらのほとんどを機能させることができませんでした。なんらかの理由で、ファイルに対するローカルな変更があると常に考えられます。stashを適用できず、パッチが適用されずcheckoutreset --hard失敗します。最終的に機能したのは、スタッシュをとしてブランチとして保存しgit stash branch tempbranchname、次に通常のブランチマージを実行することでした:git checkout masterおよびgit merge tempbranchnamehttp://git-scm.com/book/en/Git-Tools-Stashingから:

stashされた変更を再び簡単にテストする方法が必要な場合は、git stashブランチを実行して新しいブランチを作成し、作業をstashしたときに行っていたコミットをチェックアウトして、そこに作業を再適用してから、正常に適用された場合は隠しておく

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.