880

開発ブランチにコミットされていない変更がgit stashいくつかあり、 を使用してそれらを隠しましたが、それらの隠したものの中で非常に重要な変更がいくつかありました。これらの変更を元に戻す方法はありますか?

また、それ以来、隠しコード ファイルの上にいくつかの変更を加えました。

可能であれば、隠した変更を新しいブランチに取得できる可能性はありますか?

4

6 に答える 6

1509

簡単な質問に対する簡単な答えは、git stash apply

変更したいブランチをチェックアウトしてからgit stash apply. 次に、 を使用git diffして結果を確認します。

変更がすべて完了したら (apply見栄えがよくなり、隠し場所がもう必要ないことを確信できます)、<em> を使用git stash dropしてそれを取り除きます。

git stash applyではなく、常に使用することをお勧めしgit stash popます。違いは、applyを簡単に再試行しapplyたり、見たりするためにスタッシュを残しておくことです。popがスタッシュを抽出できれば、すぐにdropそれも抽出されます。 (別のブランチで)、または--index、またはそのようなものを使用することは、それほど簡単ではありません。場合はapply、いつするかを選択できますdrop

いずれにせよ、それはすべてかなりマイナーなものであり、Git の初心者にとっては、ほぼ同じはずです。(そして、この残りのすべてをスキップできます!)


より高度な、またはより複雑なことをしている場合はどうなりますか?

いわば、少なくとも 3 つまたは 4 つの異なる「git stash の使用方法」があります。上記は「方法1」、「簡単な方法」の場合です。

  1. あなたはクリーンなブランチから始めて、いくつかの変更に取り組んでいましたが、間違ったブランチでそれらを行っていたことに気付きました。現在の変更を取得して、別のブランチに「移動」したいだけです。

これは、上で説明した簡単なケースです。実行しますgit stash save(またはプレーンgit stash、同じこと)。他のブランチをチェックアウトして使用しますgit stash apply。これにより、Git のかなり強力なマージ メカニズムを使用して、Git が以前の変更をマージします。 結果を( を使用してgit diff) 注意深く調べて、気に入ったかどうかを確認しますgit stash drop。あなたは終わった!

  1. いくつかの変更を開始し、それらを隠しました。次に、別のブランチに切り替えて、さらに変更を開始し、隠したものがあることを忘れました。

ここで、これらの変更を保持または移動し、stash も適用する必要があります。

git stash save実際にはgit stash、変更の「スタック」を作成することもできます。これを行うと、2 つのスタッシュがstash作成さstash@{0}stash@{1}ます。git stash list(いつでも) を使用して、それらすべてを表示します。最新のものは、常に番号が最も小さいものです。するとgit stash drop、最新のものをドロップし、あったものをstash@{1}スタックの一番上に移動します。あなたが持っていれば、さらに、だったものは にstash@{2}なりstash@{1}ます。

apply特定のdropスタッシュも可能です:git stash apply stash@{2}など。特定のスタッシュをドロップすると、番号の大きいものだけが再番号付けされます。また、番号のないものもstash@{0}です。

たくさんの隠し場所を積み上げると、かなり厄介になる可能性があります (私が欲しかった隠し場所でしたか、stash@{7}それともそうでしたstash@{4}か? 待って、別の隠し場所をプッシュしたところ、今では 8 と 5 になっていますか?)。個人的には、これらの変更を新しいブランチに転送することを好みます。ブランチには名前がありcleanup-attempt-in-Decemberstash@{12}. (このgit stashコマンドはオプションの保存メッセージを受け取ります。これらは役に立ちますが、どういうわけか、すべての隠し場所が という名前になりWIP on branchます。)

  1. (超上級) を実行する前に、コードの特定のビットを使用git stash save -pしたか、慎重にgit add編集および/または編集しました。隠しインデックス/ステージング領域に 1 つのバージョンがあり、作業ツリーに別の (異なる) バージョンがありました。あなたはこれをすべて保存したいと思っています。を使用すると、次のように失敗することがあります。git rmgit stash savegit stash apply --index

    Conflicts in index.  Try without --index.
    
  2. git stash save --keep-index「何がコミットされるか」をテストするために使用しています。これはこの回答の範囲を超えています。代わりに、この他の StackOverflow の回答を参照してください。

複雑なケースの場合は、まず「クリーンな」作業ツリーから始めて、現在の変更を (必要に応じて新しいブランチに) コミットすることをお勧めします。そうすれば、それらを適用している「どこか」には他に何もなく、隠されている変更を試すだけです。

git status               # see if there's anything you need to commit
                         # uh oh, there is - let's put it on a new temp branch
git checkout -b temp     # create new temp branch to save stuff
git add ...              # add (and/or remove) stuff as needed
git commit               # save first set of changes

今、あなたは「きれいな」出発点にいます。または、次のようになります。

git status               # see if there's anything you need to commit
                         # status says "nothing to commit"
git checkout -b temp     # optional: create a new branch for "apply"
git stash apply          # apply stashed changes; see below about --index

覚えておくべき主なことは、「スタッシュ」コミットであり、「ブランチ上」ではなく、わずかに「おかしい/奇妙な」コミットであるということです。このapply操作は、コミットの変更内容を調べて、現在どこにいてもそれを繰り返そうとします。隠し場所はまだそこにある(apply保持している)ので、もっと調べたり、これが間違った場所だったと判断してapply別の方法で再試行したりできます。


隠し場所があるときはいつでも、 を使用してgit stash show -p、隠し場所の内容の簡略化されたバージョンを表示できます。(この単純化されたバージョンは、個別に復元される保存されたインデックスの変更ではなく、「最終的な作業ツリー」の変更のみを調べます。)コマンドは、 なしで、作業ツリーに同じ変更を加えようとします。--indexgit stash apply--index

これは、すでにいくつかの変更がある場合でも当てはまります。このコマンドは、変更されたapply作業ツリーにスタッシュを適用できます(または、少なくとも適用を試みます)。たとえば、次のことができます。

git stash apply stash      # apply top of stash stack
git stash apply stash@{1}  # and mix in next stash stack entry too

ここで「適用」順序を選択して、特定の順序で適用する特定のスタッシュを選択できます。ただし、基本的に「gitマージ」を行うたびに、マージのドキュメントが警告するように注意してください。

重要なコミットされていない変更で git merge を実行することはお勧めできません: 可能な場合でも、競合が発生した場合に元に戻すのが難しい状態になる可能性があります。

きれいなツリーから始めていくつかの操作を行っているだけの場合はgit apply、簡単に取り消すことができます: を使用git reset --hardしてきれいな状態に戻し、apply操作を変更します。(そのため、これらの複雑なケースでは、最初にクリーンな作業ツリーから始めることをお勧めします。)


考えられる最悪のケースはどうですか?

多くの高度な Git の作業を行っていて、stash を作成したとしましょう。しかし、保存した時点からブランチが分岐しすぎているため、git stash apply --index保存された stash を で適用することはできなくなりました。--index

これがgit stash branch目的です。

もし、あんたが:

  1. 元のコミットを行ったときの正確なコミットを確認してからstash
  2. 新しいブランチを作成し、最後に
  3. git stash apply --index

変更を再作成する試みは確実機能します。これが何をするかです。(そして、それが正常に適用されたので、スタッシュを削除します。)git stash branch newbranch


についてのいくつかの最後の言葉--index(それは一体何ですか?)

が何をするか--indexを説明するのは簡単ですが、内部的には少し複雑です:

  • 変更がある場合は、-ing のgit add前にそれらを (または「ステージング」) する必要があります。commit
  • したがって、 を実行したときに、 と の両方のファイルを編集した可能性git stashがありますが、ステージングしたのはそのうちの 1 つだけです。foozorg
  • したがって、隠し場所を取り戻すように頼むときは、それが物であり、追加されていない物ではない場合はいいかもgit addしれませaddedん. つまり、-edを行ったが を実行する前に戻っていない場合は、まったく同じ設定を行うとよいでしょう。ステージングされたものは、再びステージングする必要があります。変更されたがステージングされていないものは、再び変更されますがステージングされません。 git addaddfoozorgstash

このように物事を設定しようとする--indexフラグ。apply作業ツリーがクリーンな場合、これは通常うまくいきます。ただし、作業ツリーにすでにadd詰め込みが入っている場合は、ここで問題が発生する可能性があることがわかります。を省略した場合--indexapplyステージングされた/ステージングされていない設定全体を保持しようとはしません。代わりに、"stash bag"のワーキング ツリー コミットを使用して、Git のマージ機構を呼び出すだけです。ステージング済み/ステージングなしの保存を気にしない場合は、除外--indexすると、その作業がはるかに簡単になりgit stash applyます。

于 2013-09-25T11:03:52.707 に答える
88
git stash pop

すべてを元に戻します

コメントで提案されているようgit stash branch newbranchに、新しいブランチにスタッシュを適用するために使用できます。これは、次の実行と同じです。

git checkout -b newbranch
git stash pop
于 2013-09-25T10:59:50.690 に答える
35

隠し場所の内容を確認するには:-

git 隠しリスト

スタッシュ リストから特定のスタッシュ番号を適用する:-

git stash 適用 stash@{2}

または最初の隠し場所だけを適用する場合:-

git stash ポップ

注: git stash pop は stash リストから stash を削除しますが、git stash apply はしません。したがって、それに応じて使用してください。

于 2019-06-21T04:02:07.427 に答える
5

Macではこれでうまくいきました:

git stash list (すべての stash を表示)

git stash list

git stash apply (隠しリストから必要な数だけ)

このような:

git stash apply 1
于 2019-12-17T21:12:27.917 に答える