0

でチェックアウトしfeature/my-branch、実行していgit merge devます。ファイルに追加される競合マーカーは次のとおりです。

<<<<<<< HEAD
    let foo = "foo"
    let bar = "bar"
||||||| merged common ancestors
    let baz = "baz"
    let bar = "bar"
=======
    let baz = "baz"
    let qux = "qux"
>>>>>>> dev

次に実行しgit mergetoolます。私p4mergetoolのmergetoolとして設定しましたが、機能しているようです。私の.gitconfig

[merge]
    tool = p4mergetool
    conflictstyle = diff3
[mergetool "p4mergetool"]
    cmd = /Applications/p4merge.app/Contents/Resources/launchp4merge $PWD/$BASE $PWD/$REMOTE $PWD/$LOCAL $PWD/$MERGED
    trustExitCode = true

auto は上記のgit mergetool競合を次のように解決します (ツールに表示される競合は 0)。

let foo = "foo"
let qux = "qux"

HEAD と dev が競合していても、1 つのブランチが 1 つの行を更新し、別のブランチが別の行を更新したことがわかります。したがって、おそらく私たちが望むものを推測できます。

私の質問は次のとおりです。

  1. 実行/構成する方法、git-mergetoolまたはp4mergetool特にこの仮定を行わずに競合を表示する方法はありますか?
  2. 両方のコマンドを実行する必要がありますか:

    git merge dev
    git mergetool
    

    この競合を自動的に解決するには?つまり、次の出力が生成されます。

    let foo = "foo"
    let qux = "qux"
    

別の言い方をすれば、merge生成するコマンドを実行するだけで使用できる git マージ戦略/引数はありますか。

let foo = "foo"
let qux = "qux"
4

1 に答える 1

0

HEAD と dev が競合していても、1 つのブランチが 1 つの行を更新し、別のブランチが別の行を更新したことがわかります。したがって、おそらく私たちが望むものを推測できます。

その通りです。

  1. 実行/構成する方法、git-mergetoolまたはp4mergetool特にこの仮定を行わずに競合を表示する方法はありますか?

git mergetoolは仮定をしていないので、それを行っているに違いないと結論付けることができp4mergetoolます。ただし、持っていp4mergetoolないので、これを変更するための構成ノブがあるかどうかはわかりません。

  1. 両方のコマンドを実行する必要がありますか...

はい: Git 独自のマージはちょっとばかげていて、まあ、左側のこの範囲の変更が右側のこの別の範囲の変更に隣接 (接触) または重複していることに気付くだけなので、これを競合と呼び、ユーザーに処理させましょう。 . この場合、左側の変更 (baz から foo へ) は右側の変更 (bar から qux へ) の直前に行われたため、2 つの範囲が端で接触し、Git 自体が競合を宣言しました。間に 1 つの行がgit mergeあれば、競合とは呼ばずに、変更を単独で結合できたはずです。

-X ours( orを使用-X theirsすると、一方の変更を破棄し、もう一方の変更のみを使用することで競合が解決されることに注意してください。繰り返しますp4mergetoolが、独自のことを行うという点に到達することさえありません。)

git mergetoolつまり、ベース、左またはローカル--ours、右またはリモート、または--theirs一部のファイルのバージョンをマージし、3 つのファイルに対して他の Git 以外のプログラムを実行します。そのプログラムが終了したら、git mergetoolその終了コードを信頼して、ツール自体がファイルを正しくマージしたかどうかを判断するか、いくつかのファイル比較を実行するか、ファイルの作業ツリー コピーが正しいマージ済みコピーかどうかを直接尋ねることができます。

作業ツリーのコピーが正しい最終結果である (または少なくともgit mergetoolこれを信じる) 場合、git mergetoolが実行git addされ、競合が解決済みとしてマークされます。1 それ以外の場合は、競合をそのままにします。

(私は自分のエディターでマージの競合を解決するだけです。)


1ゼロ以外のインデックス スロットにファイルのコピーがある場合、ファイルはマージされません。ファイルのコピーがスロット 0 (通常のスロット番号) に 1 つある場合、ファイルはマージされます。Git の低レベルの診断的なコマンド ( git ls-index --stage、実際)を使用する場合を除いて、これらのステージング スロット番号を実際に確認git statusすることはできませんが、ファイルがマージされていないことを呼び出し、それが 3 つのスロットすべて ( UU) にあるのか、左側だけにあるのかを示します。または右のもの(UDおよびDUそれぞれ)。git status名前変更/名前変更の競合があるファイルのマージ ベース コピーを表す、スロット 1 のファイルについて何を言っているのかわかりません。

通常、git addorを使用git rmして、より高い番号のスロットを上書きします。解決されたファイルを競合状態に復元したいというまれなケースでは、git checkout -mそれを行うことができます。

于 2020-04-08T20:43:52.027 に答える