Git:以前のコミットへの変更をマージする適切な方法(手動で巻き戻しと再生を行う?)

私はこのシナリオに対処する正しい方法がgitにあるのかどうかはわかりません。何があっても奇妙な結果が得られます。

私はコミニッシュAでファイルのバージョンXを持っています。時間の経過とともに、このファイルは変更され、コミットA 'になりました。

誰かがコミットAに含まれていたファイルの修正版であるファイルX 'を私にメールします。重要:この変更は帯域外(電子メールとgitではなく)であり、期限切れですファイルのバージョン)。

私はgitの用語で何をしたいのか正確に知っていますが、私はそれを取り除く最もクリーンな方法としては巻き戻し、コミット、リプレイについてはわかりません。私はそれが単純であると想定していると思いますが、gitはリベースするときにこれを内部的に行いますが、自分で動作させることはできません。

私がやったこと:

  • コミットAに基づいてチェックアウトし、新しいブランチBを作成します。
  • 変更したファイルをコピー&ペーストする
  • 変更を確定する
  • 支店支店のマスター
  • ブランチBをマージする

私の問題は、ブランチBとマスターとのマージによってファイル内のすべての行が競合するということです。

ファイルの変更(私はこれが理由だと思います)は次のとおりです:

バージョンA:

line 1
line 2
line 3

ブランチマスタ:

line 1, file 1
line 2, file 1
line 3, file 1

メールで送信されたファイル:

line 1
line B
line 3

ご覧のように、ブランチマスタにはすべての行の変更が含まれていますが、行はそのまま残っています。アウトオブバンドの変更は、ライン2の変更です。

マージすると、文書内のすべての行が競合していることがわかります。 gitが2行目の変更を2つのリビジョンにマージできないのかどうかはわかりますが、なぜ3行すべてが矛盾しているのかわかりません。

誰かが私を助けてくれますか?

2
あなたはラインの終わりをチェックしましたか? Windows CRLF vs Unix/Max LF。デフォルトのgit設定では、本当に競合ではない競合にフラグを立てることができます。
追加された 著者 ctcherry,
私はautocrlfを使用しています。
追加された 著者 Mahmoud Al-Qudsi,
@ピーター:理由はまったくありません。実際、それが私がやったことです。しかし、私はこのアプローチがなぜ機能していないのか知りたくありません。
追加された 著者 Mahmoud Al-Qudsi,
リワインド、パッチ、リプレイのアプローチが単にdelta = diff X X 'を計算するよりもうまくいくべき理由を説明し、あなたの最新バージョンのXにパッチ "delta"を適用する理由を説明できますか? "out of band"パッチの影響を受ける行は、ファイルのgit履歴の変更によっても変更されている可能性がありますが、それは(あなたによって)直接解決されなければならないか、解決されるかどういうわけか(gitによって) "再生"シーケンスの間に。
追加された 著者 Peter,

3 答え

私はあなた自身の質問に答えたと思います。

ご覧のとおり、ブランチマスタにはすべての行の変更が含まれています。

マージするとき、Gitはどの変更がより重要か分かりません。あなたはこの選択を自分で行わなければなりません。

1
追加された
Gitは、実際に競合が発生した場合、近くにあるすべての変更された行を競合としてマークします。どこかに不変の行がある場合(たとえば、いくつかの空白行)、競合のあるグループだけが競合としてマークされます。
追加された 著者 Greg Hewgill,
私はそれを得る。しかし、ライン1と3はマスターでのみ変更され、新しいブランチでは変更されません。彼らはなぜ争ってくるの?
追加された 著者 Mahmoud Al-Qudsi,
私の実際のケースには6行あり、4番目のものだけが変更されています。このウィンドウを縮小できますか?
追加された 著者 Mahmoud Al-Qudsi,

私はこれが "正しい"解決策であるかどうかはわかりませんが、別の回避策がなければ、私はこれを受け入れるでしょう:

gitが外部差分/マージエディタを使用するように設定することで、この場合は驚くほど強力なBeyondCompare3を使用することができました。 BC3には、より細かい変更の「ブロック」があり、同じ行の変更を検出します。手動で変更をマージする必要がありましたが、個別に変更された行は変更された行だけがマークされていました(ただし、Gitはすでに周囲のブロックを修正して検出していました。

1
追加された

私が間違っている場合は私を修正しますが、 git merge B ではなく、最後のステップとして git rebase B を実際に実行したいようです。

しかし、3行すべてでマージ競合が発生している可能性があります。なぜなら、gitは行が1〜3行ではなく、2行目だけであると想定したくないからです。

0
追加された
この場合、rebaseとmergeの両方で同じ結果が得られます。マージ競合の感度を「ダイヤルダウン」する方法はありませんか?各行は完全に独立していることを伝えてください(コードではありません)。
追加された 著者 Mahmoud Al-Qudsi,