リモートの変更を破棄し、ファイルに「解決済み」のマークを付けるにはどうすればよいですか?


197

ローカルファイルがいくつかあり、リモートブランチからプルすると、競合が発生します。ローカルの変更を保持し、競合の原因となるリモートの変更を無視したいことを知っています。実際に「すべての競合を解決済みとしてマークし、ローカルを使用する」と言うために使用できるコマンドはありますか?


1
以下の答えは私を非常に照らしてきました。いくつかの微妙な点があり、本当に分かりやすくなっています。専門家以外のGITユーザーには、以下の投稿の下にあるすべてのコメントを読むことをお勧めします。ブライアンに感謝します。
Tom DeMille、2010年

回答:


332

git checkout--oursローカルにあるファイルのバージョンをチェックアウトするオプションがあります(--theirsこれは、プルしたバージョンであるとは対照的です)。に渡し.git checkout、ツリー内のすべてをチェックアウトするように指示できます。次に、競合を解決済みとしてマークする必要があります。これはで実行できgit add、完了したら作業をコミットします。

git checkout --ours .  # checkout our local version of all files
git add -u             # mark all conflicted files as merged
git commit             # commit the merge

注意.してgit checkoutコマンド。これは非常に重要であり、見逃しがちです。git checkout2つのモードがあります。1つはブランチを切り替え、もう1つはインデックスから作業コピーにファイルをチェックインします(別のリビジョンから最初にファイルをインデックスにプルする場合があります)。これを区別する方法は、ファイル名を渡したかどうかです。ファイル名を渡していない場合は、ブランチを切り替えようとします(ただし、ブランチも渡さない場合は、現在のブランチを再度チェックアウトしようとします)が、変更されたファイルがある場合は、そうすることを拒否しますそれが影響するだろうということ。したがって、既存のファイルを上書きする動作が必要な.場合は、から2番目の動作を取得するために、ファイル名またはファイル名を渡す必要がありますgit checkout

また、ファイル名を渡すときに--、などのでオフセットするのもよい習慣git checkout --ours -- <filename>です。これを行わず、ファイル名がブランチまたはタグの名前と一致する場合、Gitはそのファイル名をチェックアウトするのではなく、そのリビジョンをチェックアウトしたいと考えます。そのため、checkoutコマンドの最初の形式を使用します。。

Gitでの競合とマージの動作について少し詳しく説明します。他の誰かのコードにマージする場合(プル中にも発生します。プルは基本的にフェッチとそれに続くマージです)、考えられる状況はほとんどありません。

最も簡単なのは、同じリビジョンを使用していることです。この場合、あなたは「すでに最新」であり、何も起こりません。

別の可能性は、それらのリビジョンが単にあなたの子孫であるということです。その場合、デフォルトでは「早送りマージ」が行われ、マージHEADは発生せずにコミットに更新されるだけです(これは、本当に--no-ff)を使用してマージを記録したい。

次に、実際に2つのリビジョンをマージする必要がある状況に入ります。この場合、考えられる結果は2つあります。1つは、マージがきれいに行われることです。すべての変更が異なるファイルにあるか、同じファイルにありますが、十分に離れているため、両方の変更セットを問題なく適用できます。デフォルトでは、クリーンマージが行われると自動的にコミットさ--no-commitれますが、事前に編集する必要がある場合は無効にできます(たとえば、関数の名前をに変更foobar、他の誰かがを呼び出す新しいコードを追加するとfoo、クリーンマージされます、しかし壊れたツリーを生成するので、壊れたコミットを避けるためにマージコミットの一部としてそれをクリーンアップしたいかもしれません)。

最後の可能性は、実際のマージがあり、競合があることです。この場合、Gitは(衝突マーカとそれができるようにマージの多くの、そして農産物ファイルとして行います<<<<<<<=======>>>>>>>あなたの作業コピーに)。インデックス(「ステージング領域」とも呼ばれます。git addコミットする前にファイルが保存される場所)には、競合する各ファイルの3つのバージョンがあります。マージする2つのブランチの祖先からのファイルの元のバージョンHEAD、マージ元のバージョン、およびリモートブランチからのバージョンがあります。

競合を解決するには、作業コピーにあるファイルを編集して、競合マーカーを削除し、コードが動作するように修正します。それとも、あなたは1またはマージの他の側面、使用してからバージョンをチェックアウトすることができますgit checkout --oursgit checkout --theirs。ファイルを希望する状態にしたら、ファイルのマージが完了し、を使用してコミットする準備ができたことを示しgit addますgit commit。その後、を使用してマージをコミットできます。


7
パターンが完全な状態でgit add --allない限り、すべてのファイルがリポジトリに追加されるため、意図したよりも多くのファイルが追加される可能性があることに注意してください.gitignoregit add -uおそらくこの状況に適しています。マージの解決中に追加したくない追跡ファイルを編集する可能性は低くなります。
CBベイリー

おっと、ごめんなさい。そういう意味です。今それを修正しました。
ブライアンキャンベル

1
詳細な回答に感謝します。私は実際にgit checkout --oursを試し、エラーメッセージを受け取りました(今は覚えていません)。問題のファイルはdll(私たちが隠しているいくつかのもの、サードパーティの参照がほとんどです)であり、「コピーは私が欲しいものですが、マージ中にチェックアウトできません」のようなものでした.....この記事は参考資料として保管します。次回この記事が表示されたら、もう一度試してみて、機能するかどうか、またはメッセージを投稿できるかどうかを確認してください。再びありがとう
Tom DeMille、2010年

しかし、あなたの説明はプロセスについて私に多くを明らかにします、もう一度感謝します...追加質問:マージをクリアしたら、gitに.origファイルを削除させる方法はありますか?
Tom DeMille、2010年

2
あなたがする必要がありますgit checkout --ours ..重要です。ファイル名(この場合はディレクトリ全体)を渡すと、の2つの異なる操作モードが選択されcheckoutます。1つはブランチを切り替え、もう1つはインデックスから作業コピーにファイルを移動します。私は同意します、それは非常に混乱しています。git checkout --ours -- <filename>一度に個々のファイルをチェックアウトすることもできます。
ブライアンキャンベル

23

衝突の原因を確認します。それがの結果である場合は、Brian Campbell回答をgit merge参照してください。

しかし、がの結果であるgit rebase場合、リモート(その)変更を破棄してローカル変更を使用するには、次のことを行う必要があります。

git checkout --theirs -- .

アップストリームブランチがチェックアウトされているため」リベース中にスワップされる方法とその方法については、ourstheirsなぜ「」と「の意味がになっているのか」を参照してください。ourstheirs

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