621

この質問で尋ねられたように、すべての変更をコミットに追加せずに競合を解決する方法も知りたいですgit stash pop(競合のない「git stash pop」と同じように)。

私の現在のアプローチは、次のように行うため、非常にクールではありません。

git stash pop  # -> CONFLICT
git stash drop
# [resolve conflict]
# [add conflict files]
git reset HEAD # <all files that are in commit-mode>

再現方法:

mkdir foo; cd foo; git init
echo "1" > one
echo "2" > two
git add -A; git commit -m "first"
echo "1.1" > one
echo "2.1" > two
git stash
echo "2.2" > two
git commit -a -m "second"
echo "Only this file would stay in HEAD without the conflict" > third
git add third
git stash pop
git status

2016-06-27: 'third' という新しいファイルを例に追加して、scy のソリューションのような回避策は空の HEAD に対してのみ機能するが、HEAD に次のような同じコンテンツがないという最初の問題は修正されないことを示します。git stash pop衝突のないために。

4

11 に答える 11

723

他の答えに従わないでください...

もちろん、あなたはそれらに従うことができます。しかし、コミットを行ってからブランチをリセットして、作成したばかりのコミットを削除し、他の回答で提案されている同様の回避策が、この問題を解決するためのクリーンな方法だとは思いません。

クリーン ソリューション

次の解決策は、私にとってははるかにクリーンなようであり、Git 自体によっても提案されていますgit status—競合のあるリポジトリで実行してみてください:

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

注:このrestoreコマンドは、Gitバージョン 2.23.0で導入されました。git reset HEAD <file>...古いバージョンの Gitでは、 の代わりにコマンドを使用することが推奨されていましたgit restore --staged <file>...。を使用して、ステージング領域 ( indexgit resetと呼ばれる) 内のすべてのファイルのステージングを解除することもできます。Restore コマンドに相当するものは(ドットが必要で、任意のファイルを指定します) です。現在、これらのコマンドはどれでも使用でき、結果は同じです。これらのコマンドの違いについて知りたい場合は、ドキュメントを確認してください。git restore --staged .

それでは、Gitが提案することをしましょう(無意味なコミットを作成して元に戻すことなく):

  1. 手動で (または理想的にはいくつかのマージ ツールを使用して、以下を参照) 競合を解決します。
  2. git restore --staged .競合を解決済みとしてマークし、ステージング領域内のすべてのファイルのステージングを解除するために使用します。特定のファイルのみをアンステージする場合は、git restore --staged <file>代わりに コマンドを使用してください。事前に実行する必要はありませんgit add
  3. git stash drop最後に、 Git はコンフリクト時に自動的にそれを行わないため、stash を で削除します。

コマンドライン コマンドに変換:

$ git stash pop

# ...resolve conflict(s)

$ git restore --staged .

$ git stash drop

デフォルトの動作の説明

競合を解決済みとしてマークするには、 と の 2 つの方法がありgit addますgit restore --staged <file>...。whilegit restore --staged <file>...は、競合を解決済みとしてマークし、ファイルをインデックスから削除します。git add競合も解決済みとしてマークしますが、ファイルはインデックス内に保持します。

競合が解決された後にインデックスにファイルを追加するのは意図的なものです。このようにして、以前の stash からの変更と、競合が解決された後に行った変更を区別できます。気に入らない場合は、 を使用していつgit restore --staged .でもインデックスからすべてを削除できます。

マージ ツール

競合を解決するには、手動で行うのではなく、 KDiff3Meldなどの3 方向マージ ツールを使用することを強くお勧めします。通常、競合のすべてまたは大部分を自動的に解決します。時間を大幅に節約できます。

于 2014-12-09T15:09:13.260 に答える
306

オリジンからプルするために変更をスタッシュするシナリオがあるとします。おそらく、ローカルの変更がdebug: true一部の設定ファイルにあるためです。プルすると、誰かがそこに新しい設定を導入し、競合が発生します。

git status言います:

# On branch master
# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#   both modified:      src/js/globals.tpl.js
no changes added to commit (use "git add" and/or "git commit -a")

わかった。私は Git が提案したことに従うことにしました: 私は競合を解決し、コミットしました:

vim src/js/globals.tpl.js
# type type type …
git commit -a -m WIP   # (short for "work in progress")

これで、作業コピーは目的の状態になりましたが、不要なコミットを作成してしまいました。作業コピーを変更せずにそのコミットを取り除くにはどうすればよいですか? 待ってください、そのための人気のあるコマンドがあります!

git reset HEAD^

私の作業コピーは変更されていませんが、WIP コミットはなくなりました。それがまさに私が欲しかったものです!(--softここでは使用していないことに注意してください。スタッシュに自動マージされたファイルがある場合、それらは自動ステージングされ、これらのファイルは後で再度ステージングされることになるためですreset。)

しかし、もう 1 つ残っています。 のマニュアル ページでgit stash popは、「状態の適用は競合で失敗する可能性があります。この場合、スタッシュ リストから削除されません。手動で競合を解決し、git stash drop後で手動で呼び出す必要があります。」それがまさに今私たちがしていることです:

git stash drop

そして完了。

于 2013-08-13T15:14:44.483 に答える
89

競合を解決するために行った変更を追加する代わりに、変更をgit reset HEAD fileステージングせずに競合を解決するために使用できます。

ただし、このコマンドを2回実行する必要がある場合があります。1回は競合を解決済みとしてマークし、もう1回は競合解決ルーチンによってステージングされた変更のステージングを解除します。

現在はありませんが、これらの両方を同時に行うリセットモードがあるはずです。

于 2011-10-28T17:49:04.713 に答える
38
git checkout stash -- .

私のために働いた。

注意: スタッシュからの変更を作業コピーにマージしようとせず、代わりにスタッシュ ファイルで上書きするため、これは危険な場合があります。そのため、コミットされていない変更が失われる可能性があります。

于 2014-09-09T18:09:52.520 に答える
28
git add .
git reset

git add .競合を解決したことをgitに伝えるすべてのファイルをステージングします

git resetコミットを作成せずにステージングされたすべてのファイルをステージング解除します

于 2016-09-28T19:16:21.687 に答える
10

問題ありません。simplegit reset HEADは、ファイルを非競合のように変更されたままにするため、探しているものですgit stash pop

唯一の問題は、競合するファイルにまだ競合タグがあり、git が「both_modified」フラグと競合していると報告しなくなることです。これは便利です。

これを防ぐには、実行する前に競合を解決する (競合するファイルを編集して修正する)git reset HEADだけでいいのです...

このプロセスの最後に、スタッシュはキューに残るので、 aを実行しgit stash dropてクリアしてください。

これは私に起こり、この質問をグーグルで検索したため、解決策がテストされました。

随分きれいになったと思いますが…

于 2020-10-02T05:20:21.880 に答える
5

これはあなたが探している答えかもしれないようです、私はまだこれを個人的に試していませんが、それはうまくいくかもしれないようです。このコマンドを使用すると、GITは、コミットのためにすべてを追加しようとせずに、以前と同じように変更を適用しようとします。

git stash apply --index

ここに完全な説明があります:

http://git-scm.com/book/en/Git-Tools-Stashing

于 2012-03-01T19:16:41.130 に答える
2

git stash branchこれにより、新しいブランチが作成され、作業をスタッシュしたときに行っていたコミットがチェックアウトされ、そこに作業が再適用され、正常に適用された場合はスタッシュが削除されます。これをチェック

于 2014-08-12T12:46:39.767 に答える