プル中の変更を優先してGitマージの競合を解決する


1226

プルされた変更を優先してgitマージの競合を解決するにはどうすればよいですか?

基本的に、競合のgit mergetoolないすべての変更を保持しながら、すべての競合を通過する必要なく、すべての競合する変更を作業ツリーから削除する必要があります。できれば、後でではなく引っ張っているときにこれを実行します。




3
@DanDascalescu受け入れられた答えはこの質問に答えないので、明らかにそれは重複ではありません。さらに、そのほかの質問は非常にあいまいです。何が尋ねられたかを伝えるのは非常に困難です。全体として私はあなたに同意することはできません。これで何を指摘しますか?
sanmai 2014

2
@sanmai 2つの答えがあり、そのうちの1つを受け入れました。回答に何を期待しているのか、ここにどれだけ詳しく説明したいですか。
エドワードトムソン

2
@EdwardThomsonも、実際に私が最初の答えは、この評判を与えることを考えていたが、あなたが頼めば良い答えが起動した場合、私は待つと表示される場合があります
sanmai

回答:


1219
git pull -s recursive -X theirs <remoterepo or other repo>

または、単に、デフォルトのリポジトリの場合:

git pull -X theirs

すでに競合状態にある場合...

git checkout --theirs path/to/file

40
これ-s recursiveはデフォルトのマージ戦略であるため、ここでは冗長であることに注意してください。したがってgit pull -X theirs、これをに簡略化できますgit pull --strategy-option theirs。これは基本的にと同等です。

5
これを行うと、そのMERGING状態に戻ります。その後git merge --abort、再試行できますが、毎回マージが発生することになります。…リベースが自分のアップストリームにプッシュされたことは知っているので、おそらくそれが原因ですか?
ベンジョン

22
に注意してくださいgit checkout --theirs path/to/file。リベース中にそれを使用し、予期しない結果を得ました。ドキュメントで説明が見つかりました:git rebaseとgit pull --rebaseの実行中、私たちと彼らの入れ替えが表示される場合があります。--oursは変更がリベースされるブランチからのバージョンを提供し、--theirsはリベースされる作業を保持するブランチからバージョンを提供します。
Vuk Djapic 2017

10
git checkout --theirs/--ours pathマニュアルページには、マージされていないパスでも機能することが記載されていることに注意してください。したがって、パスに競合がなかった場合、すでにマージされているため、このコマンドは何もしません。これは、たとえば、サブフォルダ全体の「それら」のバージョンが必要な場合に問題になることがあります。したがって、そのような場合はgit checkout MERGE_HEAD path、コミットハッシュを実行または使用する方が安全です。
fsw 2017

4
git pull -X theirs競合がある場合(別のコミッターがgit push -fリモートに実行した場合など)はマージコミットを作成します。マージコミットが不要な場合は、代わりに実行してくださいgit fetch && git reset --hard origin/master
Dan Dascalescu 2018年

985

再帰的な "theirs"戦略オプションを使用できます

git merge --strategy-option theirs

から:

ours
    This option forces conflicting hunks to be auto-resolved cleanly by 
    favoring our version. Changes from the other tree that do not 
    conflict with our side are reflected to the merge result.

    This should not be confused with the ours merge strategy, which does 
    not even look at what the other tree contains at all. It discards 
    everything the other tree did, declaring our history contains all that
    happened in it.

theirs
    This is opposite of ours.

注:manページが言うように、「私たち」のマージ戦略オプションは、「私たち」マージとは非常に異なっている戦略


詳細な説明は次のとおり
2010/01/29

227
またgit checkout --theirs、1つの競合するファイルを操作する場合
dvd

48
既に競合解決状態にある場合、これは機能しません。その場合、解決するための最良の方法はgit checkout <ref to theirs> -- the/conflicted.file; そしてgit add彼らの変化。
ThorSummoner 2014

54
@ThorSummonerその場合、git checkout --theirs path / of / fileがあります。そうすれば、正しいハッシュを手動で検索する必要がなくなります。
Ikke

8
@Ikkeあなたが私に尋ねるなら、それは基本的にそれ自身の答え(そしてそれで受け入れられた答え)であるべきです。
ThorSummoner 2014

473

すでに競合状態にあり、それらすべてを受け入れるだけの場合:

git checkout --theirs .
git add .

反対のことをしたい場合:

git checkout --ours .
git add .

これはかなり抜本的ですので、実行する前に、このようにすべてを完全に消去したいことを確認してください。


47
または、を使用せず、.チェックアウトするドットの代わりにファイルを指定します。「抜本的」ではなく、おそらくあなたがやりたいことを正確に。
マンロー

10
ファイルが他のブランチから削除されている場合、これは機能しません: '<file>'にはバージョンがありません
Japster24

3
できればさらに賛成票を投じます。この答えに時々戻ってきます。
tarikki 2016

6
git add -u代わりに使用して、バージョン管理されていないファイルをスキップします。
Sudipta Basak

3
ファイルの3つの変更、1つは競合、2つは競合なしの仮説の場合、この解決策は競合しない変更を適用し、競合する変更を解決しますか?それとも、競合しない変更を無視して、私たちのバージョンのみを使用しますか?
pedromarce 2017

222

わかりました、私がちょうどいたシナリオを想像してください:

あなたはmerge、または多分を試みcherry-pick、そしてあなたは

$ git cherry-pick 1023e24
error: could not apply 1023e24... [Commit Message]
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

ここで、競合するファイルを表示し、変更を保存したくない場合。上記の私の場合、ファイルは私のIDEが自動追加した改行だけで競合していました。変更を元に戻して変更を受け入れるには、最も簡単な方法は次のとおりです。

git checkout --theirs path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php

これの逆(着信バージョンを自分のバージョンで上書きする)は

git checkout --ours path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php

驚いたことに、私はこの答えをネット上で簡単に見つけることができませんでした。


15
git status間でcheckoutとを実行してaddも、ファイルは「両方が変更された」と表示されます。
司教

競合状態にあるすべてのファイルに対してこれを行う方法があるかどうか知っていますか?もしそうなら、それはあなたの答えへの素晴らしい拡張になるでしょう。
Drew Noakes 2018年

2
私は、次の操作を行います。 git reset --hard その後、 git pull [remote server name] [branch name] -Xtheirs(マージを元に戻す私のものの上に新しいものを引く) -ではないことを確認、この何をしたい場合。
ssaltman

38

git pull -X theirs答えは醜いマージコミットを作成、または発行することができます

エラー:次のファイルに対するローカルの変更は、マージによって上書きされます:

たとえば常に常に起点のミラーであるはずのクライアント上で、リポジトリからのファイルに対するローカルの変更を単に無視したい場合は、これを実行します(master必要なブランチに置き換えます)。

git fetch && git reset --hard origin/master

どのように機能しますか?git fetchありませんgit pullが、マージしません。次にgit reset --hard、作業ツリーを最後のコミットに一致させます。リポジトリ内のファイルに対するローカルの変更はすべて破棄されますが、新しいローカルファイルはそのまま残ります。


1
+1- git fetch && git reset --hard {remote}/{branch}私の問題を解決したものでした。自分の変更を完全に破棄して、ブランチの「自分たちの」状態を優先する必要がありましたgit pull -X theirsが、一部の移動/名前変更されたファイルで窒息しました。ありがとう!
Ivaylo Slavov

23

gitマージ後、競合が発生し、自分または

git checkout --theirs .
git checkout --ours .

競合するチャンクごとにこれをどのように行うのですか?上記はファイルレベルで機能し、競合するファイルが持つ可能性のある競合しないチャンクをすべて破棄します。
ジャニ

21

特定のブランチのバージョンとのすべての競合を解決するには:

git diff --name-only --diff-filter=U | xargs git checkout ${branchName}

したがって、すでにマージ状態にあり、競合するファイルのマスターバージョンを保持したい場合は、次のようにします。

git diff --name-only --diff-filter=U | xargs git checkout master

そして、パイプxargsにアクセスできないウィンドウの人々のために、これはどのように翻訳されますか?
2016

変更を完全にスキップしませんか?紛争状態にないものでも?
Valentin Heinitz、2018年

これは私がやったことです。残念ながら、その後、git cherry-pick --continue またはgit commit --allow-emptyこれらの変更をコミットするためのコマンドを、この痛みを自動化することになり、コマンドが必要とされるの背後にはシステム、なさそうです。私は現在、.git/COMMIT_EDITMSGファイルの存在をテストすることでこれを解決していますが、それはハックルで壊れやすいようで、常に機能することはまだわかりません。
Konrad Rudolph、

これは良いことです。つまり、一部を手動で解決する(そして実行するgit add)場合、これを介して残りを一括解決できます。git checkout --ours/ git checkout --theirsも便利です。
rcoup

18

時々これが機能しないことに注意してください:

git checkout --ours path / to / file

または

git checkout-それらのパス/ to / file

HEADが私たちのものであり、MERGE_HEADが彼らのものであると仮定して、代わりにこれを行いました

git checkout HEAD -- path/to/file

または:

git checkout MERGE_HEAD -- path/to/file

これを実行すると、次のようになります。

git add .

詳細を知りたい場合は、こちらのtorekのすばらしい投稿を参照してください。git checkout --oursは、マージされていないファイルのリストからファイルを削除しません


12

VSコード(統合Git)IDEユーザー:

競合ファイル内のすべての着信変更を受け入れる場合は、次の手順を実行します。

1. Go to command palette - Ctrl + Shift + P
2. Select the option - Merge Conflict: Accept All Incoming

同様に、Accept All Both、Accept All Currentなど、他のオプションについても実行できます


2
これは、競合のあるすべてのファイルではなく、単一のファイルに対してのみ機能するようです。
Yoryo

1

私は、でnext-version変更されたdevelopファイル、両方のブランチの別の場所に追加されたファイルなどを大量に削除する長期実行ブランチを持っていました。

next-versionブランチの内容全体developを1つのなんとなくマージコミットに取り込みたいと思っていました。

私のために働いた上記のコマンドの組み合わせは:

git merge -X theirs next-version
# lots of files left that were modified on develop but deleted on next-version
git checkout next-version .
# files removed, now add the deletions to the commit
git add .
# still have files that were added on develop; in my case they are all in web/
git rm -r web

新しい答えではなく、多くの答えからのビットを組み合わせるだけで、部分的にはこれらすべての答えが必要になる可能性があることを安心させるためです。


1

すでに競合状態にあり、パスを1つずつチェックアウトしたくない場合。あなたは試すことができます

git merge --abort
git pull -X theirs

-1

https://git-scm.com/book/en/v2/Git-Tools-Advanced-Mergingから

これは基本的に偽のマージを行います。両方のブランチを親として持つ新しいマージコミットを記録しますが、マージするブランチは調べません。マージの結果として、現在のブランチの正確なコードを記録するだけです。

$ git merge -s ours mundo

「ours」戦略によって作成されたマージ。

$ git diff HEAD HEAD~

私たちがいたブランチとマージの結果の間に違いがないことがわかります。

これは、基本的にGitをだまして、後でマージを行うときにブランチがすでにマージされていると考えるのに役立ちます。たとえば、リリースブランチから分岐して、ある時点でマスターブランチにマージする必要がある作業を行ったとします。それまでの間、マスターのバグ修正をリリースブランチにバックポートする必要があります。バグ修正ブランチをリリースブランチにマージし、同じブランチをマスターブランチにマージすることもできます(フィックスがすでに存在している場合でも)。後でリリースブランチを再度マージするときに、バグ修正による競合は発生しません。

新しいトピックブランチの変更をマスターに反映させたい場合に役立つ状況です。-Xtheirsはいくつかの状況で競合なしにマージしないことに気づきました...例

$ git merge -Xtheirs topicFoo 

CONFLICT (modify/delete): js/search.js deleted in HEAD and modified in topicFoo. Version topicFoo of js/search.js left in tree.

この場合、私が見つけた解決策は

$ git checkout topicFoo

topicFooから、最初に-s ours戦略を使用してマスターにマージします。これにより、topicFooの状態である偽のコミットが作成されます。$ git merge -s私たちのマスター

作成されたマージコミットを確認する

$ git log

今マスターブランチをチェックアウト

$ git checkout master

トピックブランチをマージして戻しますが、今回は-Xtheirs再帰戦略を使用します。これにより、topicFooの状態のマスターブランチが表示されます。

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