stashを作業ディレクトリに適用できないのはなぜですか?


96

stashを作業ディレクトリに適用できません。

小さな話:

最初に、コミットされた変更をプッシュしようとしましたが、「最初にプルすることはできません」というメッセージが表示されました... OK、次に、GitHubからプルして、変更をプッシュします。プルしようとすると、上書きされる変更があり、変更を隠しておくべきだと言われました。OK、変更を隠しておきました...プルを行い、コミットされた変更をプッシュしました。しかし今は、作業していたコミットされていない変更を復元できません。

これはエラーです:

MyPath/File.cs already exists, no checkout
Could not restore untracked files from stash

確かに私はまだgitのすべての概念を理解していませんが、それらは私を少し混乱させます...多分私は何か間違ったことをしました。

誰かが私を解決するのを手伝ってくれるといいのですが...私は1時間以上Googleとすべてを検索してきましたが、まだ解決策を見つけていません。

ヘルプは大歓迎です。ありがとう!

回答:


74

stashに追跡されていないファイルが含まれていて、その後リポジトリに追加されたようです。試してみると、既存のファイルが上書きされるため、gitは正しく拒否します。

修正するには、そのファイルを削除し(大丈夫です、まだリポジトリ内にあります)、stashを適用してから、必要に応じてstashされたバージョンのファイルをリポジトリ内のバージョンに置き換えます。

編集:ファイルがリポジトリに追加されに、作業ツリーでのみ作成された可能性もあります。この場合、ローカルファイルを単に削除するのではなく、次のようにします。

  1. 別の場所に移動します
  2. 隠し場所を適用します
  3. 2つのファイルバージョンを手動でマージします(作業ツリーと移動)。

2
私が将来物事を隠しておく必要を回避できる方法はありますか?私はSVNから来ました、そしてそれはとても前向きです...あなたは単に更新して競合を解決してからコミットします。Gitはそれほど難しくないので、サイクルに2つのステップを追加する必要があります。再度、感謝します!
ミゲルアンジェロ2012年

2
@ミゲル:隠しておくことは障害ではありません。これは、Gitが提供する追加ツールであり、ワークフローを改善し、競合や不明瞭なコミットを回避できます。git-scm.com/docs/git-stash
Koraktor

8
答えは有効ですが、gitが「正しい」かどうかは本当にわかりません。ファイルはリポジトリ内にあるため、データ損失の危険はありません。なぜ変更を適用しないのですか?このスレッドを参照してください-git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.html
studgeek

5
この答えはあまり役に立たないと思います。git stashローカルの変更をすばやくバックアップするのに役立ちます。一連のファイルを手動で削除して復元すると、フローが中断されます。git stash branch他の答えのアプローチはより良いように聞こえますが、それでも望みよりはるかに手作業です。
ベントラー2013

この答えは、同じ状況のときに私にとって最も効果的でした。スタッシュをポップした後、最初から予想していたようにマージを行いました。
ビリーラザロ2014年

58

最も安全で簡単な方法は、おそらく再び物事を隠しておくことでしょう。

git stash -u             # This will stash everything, including unstaged files
git stash pop stash@{1}  # This will apply your original stash

その後、結果に満足したら、電話することができます

git stash drop

「安全な」隠し場所を削除します。


2
これをありがとう、多くの痛みと苦しみから私を救いました!
danjarvis 2012

9
stash popが適用され、元のstashをドロップします。安全のためにのapply代わりに使用してくださいpop
Hilbrand Bouwkamp 2012

2
実際popの組み合わせですapplydrop、だけになるdrop場合はapply、競合なしで働いていました。しかし、はい、apply通常はより安全です。
コラクトール2012

2
これは、作業ディレクトリに保持したい他の変更がないことを前提としています。この特定の質問について、彼は彼がクリーンな状態にあることを示唆しています(しかし明示的には述べていません)が、私は、ローカルの変更でここに来る他の人にそれを指摘したかったのです。
studgeek 2013

1
これは、競合する問題がコミットされていない場合にのみ問題を解決します。それらがコミットされたときに(たとえば、クリーンチェックアウトで)まったく同じメッセージが表示され、それによって状況が変わることはありません...
Jasper

56

@bentoloで述べたように、問題のあるファイルを手動で削除し、ブランチを切り替えてから、手動で追加し直すことができます。しかし、私は個人的には「git内」にとどまることを好みます。

これを行う最良の方法は、スタッシュをブランチに変換することです。ブランチになると、gitで通常のブランチ関連のテクニック/ツールを使用して、あなたが知っていて気に入っている通常の作業を行うことができます。これは実際には、リストされたエラーがない場合でも、スタッシュを操作するための有用な一般的な手法です。stashは実際には内部でのコミットであるため、うまく機能します(PSを参照)。

スタッシュをブランチに変換する

以下は、スタッシュが作成されたときにHEADに基づいてブランチを作成し、スタッシュを適用します(コミットは行いません)。

git stash branch STASHBRANCH

「stashブランチ」での作業

次に何をするかは、スタッシュとターゲットブランチ(ここではORIGINALBRANCHと呼びます)の現在の関係によって異なります。

オプション1-stashブランチを通常どおりにリベースする(stash以降の多くの変更)

ORIGINALBRANCHに多くの変更を加えた場合は、おそらくSTASHBRANCHをローカルブランチと同様に扱うのが最善です。STASHBRANCHでの変更をコミットし、ORIGINALBRANCHでリベースしてから、ORIGINALBRANCHに切り替えて、STASHBRANCHの変更をリベース/マージします。競合がある場合は、通常どおり処理します(このアプローチの利点の1つは、競合を確認して解決できることです)。

オプション2-stashに一致するように元のブランチをリセットします(stash以降の変更は制限されます)

ステージングされた変更をいくつか保持し、それからコミットしただけの場合は、追加した変更を取得するだけで、ステージングされていない場合は次のことができます。作業コピーを変更することなく、元のブランチとインデックスに戻ります。最終結果は、作業コピーの追加の隠し場所の変更になります。

git symbolic-ref HEAD refs/heads/ORIGINALBRANCH
git reset

バックグラウンド

Stashesはブランチ/タグのようなコミットです(パッチではありません)

PS、スタッシュをパッチとして考えるのは魅力的ですが(コミットをパッチとして考えるのと同じように)、スタッシュは実際には作成時のHEADに対するコミットです。適用/ポップするときは、現在のブランチにチェリーピックするのと同じようなことをしています。ブランチとタグは実際には単にコミットへの参照であるため、多くの点でスタッシュ、ブランチ、タグは、コミット(およびその履歴)を指すための異なる方法にすぎません。

作業ディレクトリを変更していない場合でも必要になる場合があります

PPS、-patchや--include-untrackedでstashを使用した直後に、このテクニックが必要になる場合があります。作業ディレクトリを変更しなくても、これらのオプションによってスタッシュが作成される場合があるため、元に戻すことはできません。その理由を完全に理解していないことを認めなければなりません。議論については、http://git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.htmlを参照してください


5
この回答は、「ロックされた隠し場所」を最も効果的に解決する方法について最も役立つ指針を提供するため、ソリューションとしてマークする必要があります。最初に「単純な削除ソリューション」を言及し、2番目のオプションとしてブランチソリューションを言及することで、おそらくそれを改善します。
ベントラー2013

8
このシナリオに直面している場合、「git stash branch STASHBRANCH」は機能しないようです(popとまったく同じエラーメッセージが表示されます)。事前にgitをリセットする必要があるかもしれません。

1私がコミットし、変更とスパゲティの混乱で自分自身を持って、などなどスタッシュこれは、分岐感謝studgeekにスタッシュをpopingことによってそれを私に外に出た
RobbZ

stashがパッチではない方法と、それらがHEADにどのように結び付けられているか(stashing時)を明確にしていただきありがとうございます。それは非常に理にかなっています。–だから...どこでも適用できるように(多くの変更がある場合)、スタッシュではなくパッチを作成する方が柔軟性/携帯性/便利さがあるケースがあると思います(そして競合を解決するだけの問題)。たぶんgit stash show -pそこに隠しておく -> *パッチ*。
Kamafeather

39

解決策:問題のファイルを削除してから、pop / applyを再度隠してみてください。他のファイルは削除しないでください。エラーで言及されたファイルのみです。

問題: Gitは時々吸います。実行するgit stash -uと、追跡されていないファイルが含まれますが(クールです)、それらの追跡されていないファイルは削除されず、残りのものの上に隠された追跡されていないファイルを適用する方法がわかりません(クールでありません!)-u


3
それが私の質問だったら、私はこの答えを受け入れたでしょう。@qwertzguyに感謝します。あなたの答えは私の問題を解決しました
Kobus Myburgh

私自身も同じ問題に遭遇し、問題のファイルを削除するまでgit stash popは適用されませんでした。それから、stashが拒否される原因となったファイルとの競合に遭遇しました。しかし、追跡されていないファイルを削除すると、ファイルが残されてしまいます。したがって、将来の自己から離れてくださいgit stash -u
notzippy

影響を受けるファイルの両方のバージョンのパーツが必要な場合の悪いアドバイス。
Walf、2016年

2
「これらの追跡されていないファイルは削除されません」 ...およびそれらをにリストしませんgit stash show。この答えにより、電球が点灯しました。
jscs 2017

2
Git用の1つは時々吸います。
ハリッシュ

29

代わりにstashのコードの違いをパッチとして適用するには、次のコマンドを使用します。

git stash show --patch | patch -p1

11
通常、匿名コードのいくつかの行を投稿するだけではなく、解決策を説明する方が良いでしょう。どのようにすれば良い答えを書くことができ、また完全にコードベースの答えを説明することもできます
Massimiliano Kraus 2017年

のパッチにgit stash show --patchは追跡されていないファイルが含まれていないため、これは私にとってはうまくいきます。
Steven Shaw、

スタッシュがプッシュされてからリポジトリに多くの変更があったため、スタッシュをポップできなかったので、この回答は非常に役に立ちました。
Erik Finnman、2018

1

これは私に何度も起こりました、私は追跡されていないファイルを git stash -uい、その結果、リポジトリに追加されてしまい、隠された変更を適用できなくなりました。

git stash pop/applyファイルを強制的に置き換える方法が見つからなかったため、まず、隠しておいた追跡されていないファイルのローカルコピーを削除し(コミットされていない変更を削除するので注意してください)、次に隠しておいた変更を適用します:

rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply

最後にgit statusgit diffや他のツールを使用して、何か不足しているものがないかどうかを確認し、削除されたファイルの一部を追加します。


保持したいコミットされていない変更がある場合は、最初に一時コミットを作成できます。

git add --all
git commit -m "dummy"
rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply

以前にコミットされた変更をローカルファイルにマージし、ダミーコミットを削除するには、適切なツールを使用します。

git reset HEAD~1

0

私の同様にブロックされたポップ操作は、残り物が無視されたためでしたファイルがです(.gitignoreファイルを参照)。Gitのステータスは追跡済みと追跡なしを示しましたが、私のアクティビティでは無視されたファイルをクリーンアップできませんでした。

詳細:私が使用したgit stash save -aして、マスターをチェックアウトしてコンパイルし、元の動作を確認してから、すべてを元に戻して編集を続けました。私が自分のブランチをチェックアウトしてポップしようとしたときに、無視されたファイルはstashの保存前からまだ残っていました。これは、マスターのチェックアウトがコミットされたファイルにのみ影響を与えるためです-無視されたファイルは消去されませんでした。そのため、ポップは失敗し、基本的に、格納されていた無視されたファイルを、まだそこにあるファイルの上に復元したくないと述べました。それらとのマージセッションを開始する方法を理解できなかったのは残念です。

最終的に、私git clean -f -d -xは無視されたファイルを削除するために使用しました。興味深いことに、私の〜30のうち、4つのファイルがクリーニング後も残っています(サブディレクトリに埋め込まれています)。それらが手動で削除されなければならなかったので、私はそれらがどのカテゴリにあるかを理解する必要があります。

それから私のポップは成功しました。



-1

その他の解決策:

cd to/root/your/project

# Show what git will be remove
git clean -n

# If all is good
git clean -f

# If not all is good, see
git clean --help

# Finish
git stash pop

質問に記載されているエラーは、スタックと作業ディレクトリの両方に存在するファイルが原因です。クリーニングでは、このファイルが追跡されていない場合にのみ修正されますが、常にそうであるとは限りません(OPの場合ではなく、プルからファイルを取得したためです)。
ザビエルポイナス2017年

-1

Git 2.14.x / 2.15(2017年第3四半期)では、2014年のqwertzguyソリューションは不要になります。

2017年第3四半期より前は、問題のファイルを削除してから、pop / appを再度隠してみてください。
次のGitリリースでは、それを行う必要はありません。

Nicolas Morey-Chaisemartin()によるcommit bbffd87(2017年8月11日)を参照してください。(による合併Junio C浜野- -0ca2f32コミット、2017年8月23日)をnmorey
gitster

stash:リセット前に追跡されていないファイルをクリーンアップ

git stash -uファイルの現在の変更により無視されなくなったファイルを含むリポジトリを呼び出すとgitignore、このファイルは隠されますが、作業ツリーから削除されません。
これは、git-stash最初にファイルの変更reset --hardをクリアするを .gitignore実行し、次にを呼び出しgit cleanて、ファイルに手を加えないためです。
これによりgit stash pop、ファイルが存在するために失敗します

このパッチは、クリーニングとリセットの順序を切り替えるだけで、このユースケースのテストを追加します。


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