csprojファイルをマージする際の競合



GitHub for Windowsの現在のバージョンでは、ほとんど目立たない効果を持つ小さな変更を行いましたが、おそらく既に気づいているでしょう。 *.csprojと同様のファイルのデフォルトのマージを変更しました。
ブランチ内の.csprojファイルを変更してから別のブランチとマージすると、以前よりも多くのマージ競合が発生する可能性があります。

なんで?

さて、以前は*.csprojファイルをマージするためにunionを使用していました。
この機能を説明する git merge-file ドキュメント:

ファイルに競合を残すのではなく、私たち(またはその両方)の側を優先して競合を解決します。

一般に、競合が発生すると、システムはこの問題の解決を試み、すべての変更を適用しようとします。
原則として、これは妥協です。 このアプローチは.gitattributesファイルでカスタマイズできます。そのため、リポジトリでこの動作を本当に使用する場合は、次を追加します。
 *.csproj merge=union 

そして、なぜあなたがこれをしたくないのか、そして私たちが最終的にこれを変更した理由を教えてください。

合併は災害に変わった


masterブランチの次の単純化されたfoo.csprojファイルと、 foo.csprojファイルから開始するとします。
 <?xml version="1.0" encoding="utf-8"?> <Project> <PropertyGroup> <Page Include="AAA.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> <Page Include="DDD.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> </PropertyGroup> </Project> 


このファイルを作成したら、コミットすることを確認しましょう
 git init . git add -A git commit -m "Initial commit of gittattributes and foo.csproj" 


次に、元の名前「branch」の下にブランチ( git checkout -b branch )を作成し、次の部分をfoo.csproj DDD.csDDD.cs間に貼り付けDDD.cs
  <Page Include="BBB.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> 


想像力が弱い人のために、このスレッドでコミットした結果を以下にリストします。
 <?xml version="1.0" encoding="utf-8"?> <Project> <PropertyGroup> <Page Include="AAA.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> <Page Include="BBB.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> <Page Include="DDD.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> </PropertyGroup> </Project> 


順番に行動する場合は、これをコミットすることを忘れないでください。
 git commit -a "Add BBB.cs element" 


それではmasterブランチに戻りましょう
 git checkout master 


そして、そこに次のピースを追加します。
 <Page Include="CCC.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> 


その結果、masterブランチには次のものが含まれるはずです。
 <?xml version="1.0" encoding="utf-8"?> <Project> <PropertyGroup> <Page Include="AAA.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> <Page Include="CCC.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> <Page Include="DDD.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> </PropertyGroup> </Project> 


そして、これはすべてコミットされています:
 git commit -a "Add CCC.cs element" 


あなたはまだここにいますか
では、 branchmasterマージしましょう
 git merge branch 


結合によるマージを使用した結果、次の結果が得られます。
 <?xml version="1.0" encoding="utf-8"?> <Project> <PropertyGroup> <Page Include="AAA.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> <Page Include="CCC.cs"> <Page Include="BBB.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> <Page Include="DDD.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> </PropertyGroup> </Project> 


くそー(yiuu)、それは私たちが望んでいたものとは全く違っていた。 「BBB.cs」は「CCC.cs」に埋め込まれているため、終了タグはありません。 これは、控えめに言っても、ひどいです。
リポジトリに.gitattributesファイルが存在せず、標準のマージアプローチを使用している場合、標準のmergeコマンドにより、修正が必要なマージの競合が発生しました。 私たちの理解では、これはあなたのプロジェクトに残る重大な間違いよりも優れています。
 <?xml version="1.0" encoding="utf-8"?> <Project> <PropertyGroup> <Page Include="AAA.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> <<<<<<< HEAD <Page Include="CCC.cs"> ======= <Page Include="BBB.cs"> >>>>>>> branch <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> <Page Include="DDD.cs"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> </PropertyGroup> </Project> 


明らかに、完全なパラレルユニバースでは、gitはgbbを使用せずにccc要素全体をbbb要素の後に配置し、これらの厄介なマージの競合を解決することを気にしません。 私たちはこの宇宙に住んでいるわけではありませんが、多分私たちのものは理想的なもののようになります。 かっこいいと聞いた。

Visual Studioで何をすべきですか?


私は最近、Twitterサブスクライバーに、Visual Studioチームにプロジェクトファイルでのファイルテンプレートのサポートの追加を求める質問に投票するように依頼しました。 MSBuildは、.csprojファイル内のワイルドカード文字を既にサポートしていますが、Visual Studioはまだそれらを使用していません。

合併の競合を解決する際の苦痛を軽減することが、そうする主な理由の1つです。 ジョーカー文字を使用してディレクトリを示すことができる場合、プロジェクトにファイルを追加するたびに*.csprojエントリを追加する必要はありません。

一方、Git用の高品質なXMLマージドライバーを作成することもできますが、これは非常に深刻なテストであり、私の同僚のMarcus Olssonはこれを確認できます。 それが単純であるか、難しい場合でも、節度があれば、すでに行われているでしょう。 奇妙なことに、これを.csprojファイルの通常の問題に限定すると、これは素晴らしいことではありませんが、一般的なマージの競合を制御するのに十分な解決策と言えますか? おそらく。

このマージドライバーを作成しても、特定の1つのバージョン管理システムのみの問題を解決できます。これは私たちにとってのみ重要です。 :trollface:

Visual Studioがこれらのアイテムを最初に並べ替えると、問題を部分的に解決できる可能性があると推測されています。 これにより、Visual Studioの要素の条件付きで非決定的な並べ替えによって発生する軽微な競合を減らすことができます。 しかし、これでは合併の問題は解決されません。 私が提示した例では、各要素は例全体でソートを保持します。 隣接するファイルが2つの異なるブランチに追加されるたびに、競合が発生する危険があります。 これは非常に頻繁に起こります。

ジョーカーキャラクターサポートは、この問題をほぼ完全に解決できます。 通知、私はほとんど言った。 時々このファイルに競合がありますが、これはめったに起こりません。

PS
運命の意志で、私はこの記事に出くわしました、私もあなたが知りたいと思うことに決めました、個人的に私はこれに絶えず遭遇します。
これが私の最初の翻訳ですので、アンケートの質問に答えてください。あなたの/私の時間をさらに過ごすかどうか知りたいです。

Source: https://habr.com/ru/post/J221999/


All Articles