マニュアル

コンフリクトの解決

時々、リポジトリからファイルを更新/マージするとき、またはワーキングコピーを別のURLに切り替えるときに、コンフリクトが発生します。コンフリクトには2種類あります。

ファイルコンフリクト

ファイルコンフリクトは、2人以上の開発者がファイルの同じ数行を変更した場合に発生します。

ツリーコンフリクト

ツリーコンフリクトは、ある開発者がファイルまたはフォルダを移動/名前変更/削除した場合に発生し、別の開発者がそれも移動/名前変更/削除したり、単に変更したりした場合に発生します。

ファイルコンフリクト

ファイルコンフリクトは、2人以上の開発者がファイルの同じ数行を変更した場合に発生します。Subversionはあなたのプロジェクトについて何も知らないため、コンフリクトの解決は開発者に委ねられます。テキストファイル内のコンフリクト箇所は、次のようにマークされます。

<<<<<<< filename
your changes
=======
code merged from repository
>>>>>>> revision
      

また、コンフリクトが発生したファイルごとに、Subversionは3つの追加ファイルをディレクトリに配置します。

filename.ext.mine

これは、ワーキングコピーを更新する前のワーキングコピーに存在していたファイルです。つまり、コンフリクトマーカーはありません。このファイルには、最新の変更のみが含まれています。

filename.ext.rOLDREV

これは、ワーキングコピーを更新する前のBASEリビジョンであったファイルです。つまり、最新の編集を行う前にチェックアウトしたファイルです。

filename.ext.rNEWREV

これは、ワーキングコピーを更新したときにSubversionクライアントがサーバーから受信したファイルです。このファイルは、リポジトリのHEADリビジョンに対応します。

TortoiseSVNコンフリクトの編集で外部マージツール/コンフリクトエディタを起動するか、テキストエディタを使用して手動でコンフリクトを解決できます。コードがどのように見えるべきかを決定し、必要な変更を行い、ファイルを保存する必要があります。TortoiseMergeなどのマージツールや、他の一般的なツールを使用する方が、一般的に簡単なオプションです。これらのツールは通常、関連するファイルを3ペインビューで表示し、コンフリクトマーカーについて心配する必要がないためです。テキストエディタを使用する場合は、文字列<<<<<<<で始まる行を検索する必要があります。

その後、TortoiseSVN解決済みコマンドを実行し、変更をリポジトリにコミットします。解決コマンドは実際にはコンフリクトを解決しないことに注意してください。変更をコミットできるように、filename.ext.mineファイルとfilename.ext.r*ファイルを削除するだけです。

バイナリファイルでコンフリクトが発生した場合、Subversionはファイル自体をマージしようとはしません。ローカルファイルは変更されず(最後に変更したとおり)、filename.ext.r*ファイルが存在します。変更を破棄してリポジトリバージョンを保持する場合は、元に戻すコマンドを使用してください。自分のバージョンを保持してリポジトリバージョンを上書きする場合は、解決済みコマンドを使用し、バージョンをコミットしてください。

親フォルダを右クリックしてTortoiseSVN解決済み...を選択すると、複数のファイルに対して解決済みコマンドを使用できます。これにより、そのフォルダ内のすべてのコンフリクトファイルが一覧表示されたダイアログが表示され、解決済みとしてマークするファイルを選択できます。

プロパティコンフリクト

プロパティコンフリクトは、2人以上の開発者が同じプロパティを変更した場合に発生します。ファイルの内容と同様に、コンフリクトの解決は開発者のみが行うことができます。

一方の変更が他方をオーバーライドする必要がある場合は、ローカルプロパティを使用して解決またはリモートプロパティを使用して解決のオプションを選択します。変更をマージする必要がある場合は、プロパティを手動で編集を選択し、プロパティ値を決定し、解決済みとしてマークします。

ツリーコンフリクト

ツリーコンフリクトは、ある開発者がファイルまたはフォルダを移動/名前変更/削除した場合に発生し、別の開発者がそれも移動/名前変更/削除したり、単に変更したりした場合に発生します。ツリーコンフリクトを引き起こす可能性のある状況は多数あり、それらのすべてがコンフリクトを解決するために異なる手順を必要とします。

Subversionでローカルでファイルが削除されると、ファイルはローカルファイルシステムからも削除されるため、ツリーコンフリクトの一部であっても、コンフリクトのオーバーレイを表示できず、右クリックしてコンフリクトを解決することはできません。変更の確認ダイアログを使用して、代わりにコンフリクトの編集オプションにアクセスしてください。

TortoiseSVNは、変更をマージする適切な場所を見つけるのに役立ちますが、コンフリクトを整理するために追加の作業が必要になる場合があります。更新後、ワーキングベースには常に、更新時のリポジトリ内の各項目のリビジョンが含まれることを覚えておいてください。更新後に変更を元に戻すと、ローカルでの変更を開始したときの方法ではなく、リポジトリの状態に戻ります。

ローカル削除、更新時の受信編集

  1. 開発者AはFoo.cを変更し、リポジトリにコミットします。

  2. 開発者Bは、ワーキングコピーでFoo.cBar.cに同時に移動するか、単にFoo.cまたはその親フォルダを削除しました。

開発者Bのワーキングコピーを更新すると、ツリーコンフリクトが発生します。

  • Foo.cはワーキングコピーから削除されましたが、ツリーコンフリクトとしてマークされています。

  • コンフリクトが削除ではなく名前変更の結果である場合、Bar.cは追加済みとしてマークされますが、開発者Aの変更は含まれていません。

開発者Bは、開発者Aの変更を保持するかどうかを選択する必要があります。ファイルの名前変更の場合、変更をFoo.cから名前変更されたファイルBar.cにマージできます。単純なファイルまたはディレクトリの削除の場合、開発者Aの変更を含む項目を保持し、削除を破棄することを選択できます。または、何もせずにコンフリクトを解決済みとしてマークすることにより、開発者Aの変更を事実上破棄します。

コンフリクト編集ダイアログは、名前変更されたBar.cの元のファイルを見つけることができる場合、変更をマージすることを提案します。移動元の可能性のあるファイルが複数ある場合は、これらのファイルごとにボタンが表示され、正しいファイルを選択できます。

ローカル編集、更新時の受信削除

  1. 開発者AはFoo.cBar.cに移動し、リポジトリにコミットします。

  2. 開発者Bは、ワーキングコピーでFoo.cを変更します。

またはフォルダ移動の場合...

  1. 開発者Aは親フォルダFooFolderBarFolderに移動し、リポジトリにコミットします。

  2. 開発者Bは、ワーキングコピーでFoo.cを変更します。

開発者Bのワーキングコピーを更新すると、ツリーコンフリクトが発生します。単純なファイルコンフリクトの場合

  • Bar.cは、通常のファイルとしてワーキングコピーに追加されます。

  • Foo.cは、(履歴付きで)追加済みとしてマークされ、ツリーコンフリクトがあります。

フォルダコンフリクトの場合

  • BarFolderは、通常のフォルダとしてワーキングコピーに追加されます。

  • FooFolderは、(履歴付きで)追加済みとしてマークされ、ツリーコンフリクトがあります。

    Foo.cは変更済みとしてマークされます。

開発者Bは、開発者Aの再編成を受け入れ、変更を新しい構造の対応するファイルにマージするか、単にAの変更を元に戻してローカルファイルを保持するかを決定する必要があります。

ローカルの変更をリシャッフルとマージするには、開発者Bは最初に、コンフリクトが発生したファイルFoo.cがリポジトリでどのファイル名に変更/移動されたかを知る必要があります。これは、ログダイアログを使用することで実行できます。次に、正しいソースファイルを表示するボタンを使用して、コンフリクトを解決します。

開発者BがAの変更が間違っていたと判断した場合、コンフリクトエディタダイアログで解決済みとしてマークボタンを選択する必要があります。これにより、コンフリクトが発生したファイル/フォルダは解決済みとしてマークされますが、開発者Aの変更は手動で削除する必要があります。ここでも、ログダイアログは移動されたものを追跡するのに役立ちます。

ローカル削除、更新時の受信削除

  1. 開発者AはFoo.cBar.cに移動し、リポジトリにコミットします。

  2. 開発者BはFoo.cBix.cに移動します。

開発者Bのワーキングコピーを更新すると、ツリーコンフリクトが発生します。

  • Bix.cは、履歴付きで追加済みとしてマークされます。

  • Bar.cは、ステータス「通常」でワーキングコピーに追加されます。

  • Foo.cは削除済みとしてマークされ、ツリーコンフリクトがあります。

このコンフリクトを解決するには、開発者Bは、コンフリクトが発生したファイルFoo.cがリポジトリでどのファイル名に変更/移動されたかを知る必要があります。これは、ログダイアログを使用することで実行できます。

次に、開発者Bは、Foo.cの新しいファイル名として、開発者Aが行ったものと自身が行った名前変更のどちらを保持するかを決定する必要があります。

開発者Bが手動でコンフリクトを解決した後、ツリーコンフリクトはコンフリクトエディタダイアログのボタンで解決済みとしてマークする必要があります。

ローカルで欠落、マージ時の受信編集

  1. トランクで作業している開発者Aは、Foo.cを変更してリポジトリにコミットします。

  2. ブランチで作業している開発者Bは、Foo.cBar.cに移動してリポジトリにコミットします。

開発者Aのトランクの変更を開発者Bのブランチワーキングコピーにマージすると、ツリーコンフリクトが発生します。

  • Bar.cは、ステータス「通常」ですでにワーキングコピーに存在します。

  • Foo.cは、ツリーコンフリクトがある状態で欠落としてマークされます。

このコンフリクトを解決するには、開発者Bはコンフリクトエディタダイアログでファイルを解決済みとしてマークする必要があります。これにより、コンフリクトリストからファイルが削除されます。次に、リポジトリから欠落しているファイルFoo.cをワーキングコピーにコピーするか、開発者AのFoo.cへの変更を名前変更されたBar.cにマージするか、コンフリクトを解決済みとしてマークして他に何も行わないことで変更を無視するかを決定する必要があります。

リポジトリから欠落しているファイルをコピーしてから解決済みとしてマークすると、コピーは再度削除されることに注意してください。最初にコンフリクトを解決する必要があります。

ローカル編集、マージ時の受信削除

  1. トランクで作業している開発者Aは、Foo.cBar.cに移動してリポジトリにコミットします。

  2. ブランチで作業している開発者Bは、Foo.cを変更してリポジトリにコミットします。

  1. トランクで作業している開発者Aは、親フォルダFooFolderBarFolderに移動してリポジトリにコミットします。

  2. ブランチで作業している開発者Bは、ワーキングコピーでFoo.cを変更します。

開発者Aのトランクの変更を開発者Bのブランチワーキングコピーにマージすると、ツリーコンフリクトが発生します。

  • Bar.cは追加済みとしてマークされます。

  • Foo.cは、ツリーコンフリクトがある状態で変更済みとしてマークされます。

開発者Bは、開発者Aの再編成を受け入れ、変更を新しい構造の対応するファイルにマージするか、単にAの変更を元に戻してローカルファイルを保持するかを決定する必要があります。

ローカルの変更をリシャッフルとマージするには、開発者Bは最初に、コンフリクトが発生したファイルFoo.cがリポジトリでどのファイル名に変更/移動されたかを知る必要があります。これは、マージソースのログダイアログを使用することで実行できます。コンフリクトエディタは、マージで使用されたパスを認識していないため、ワーキングコピーのログのみを表示するため、自分で見つける必要があります。変更は手動でマージする必要があります。現在、このプロセスを自動化または簡素化する方法はありません。変更が移植されたら、コンフリクトが発生したパスは冗長になり、削除できます。

開発者BがAの変更が間違っていたと判断した場合、コンフリクトエディタダイアログで解決済みとしてマークボタンを選択する必要があります。これにより、コンフリクトが発生したファイル/フォルダは解決済みとしてマークされますが、開発者Aの変更は手動で削除する必要があります。ここでも、マージソースのログダイアログは移動されたものを追跡するのに役立ちます。

ローカル削除、マージ時の受信削除

  1. トランクで作業している開発者Aは、Foo.cBar.cに移動してリポジトリにコミットします。

  2. ブランチで作業している開発者Bは、Foo.cBix.cに移動してリポジトリにコミットします。

開発者Aのトランクの変更を開発者Bのブランチワーキングコピーにマージすると、ツリーコンフリクトが発生します。

  • Bix.cは、(変更されていない)通常のステータスでマークされます。

  • Bar.cは、履歴付きで追加済みとしてマークされます。

  • Foo.cは、ツリーコンフリクトがある状態で欠落としてマークされます。

このコンフリクトを解決するには、開発者Bは、コンフリクトが発生したファイルFoo.cがリポジトリでどのファイル名に変更/移動されたかを知る必要があります。これは、マージソースのログダイアログを使用することで実行できます。

次に、開発者Bは、Foo.cの新しいファイル名として、開発者Aが行ったものと自身が行った名前変更のどちらを保持するかを決定する必要があります。

開発者Bが手動でコンフリクトを解決した後、ツリーコンフリクトはコンフリクトエディタダイアログのボタンで解決済みとしてマークする必要があります。

その他のツリーコンフリクト

コンフリクトがファイルではなくフォルダに関連しているという理由だけで、ツリーコンフリクトとしてラベル付けされる他のケースもあります。たとえば、トランクとブランチの両方に同じ名前のフォルダを追加してから、マージしようとすると、ツリーコンフリクトが発生します。マージターゲットからフォルダを保持する場合は、コンフリクトを解決済みとしてマークするだけです。マージソースのフォルダを使用する場合は、最初にターゲットのフォルダをSVN削除し、再度マージを実行する必要があります。さらに複雑な必要がある場合は、手動で解決する必要があります。

TortoiseSVN ホームページ