もう何年もKDiff3ユーザーですが、無料のマージツールならP4Mergeも良いよと聞いたので、少し試してみました。
MercurialやGitのマージツールとして使うため、3-way mergeが前提です。
できるだけ自動解決したいので、うまく自動解決する手段があればそちらを優先します。
マージ対象のコード
今回試したマージ対象のコードは以下の3つです。意図的にコンフリクトが発生するような内容にはしていますが、多人数で同じモジュールを変更するような開発をしていると、しばしばこのような状況は起こるかと思います。
base.py
class User: """ユーザークラス """ def __init__(self, name): self.name = name
local.py
base.pyに対してGroupクラスをファイルの末尾に追記しています。
class User: """ユーザークラス """ def __init__(self, name): self.name = name class Group: """グループクラス """ def __init__(self, name): self.name = name self.users = []
other.py
base.pyに対してPermissionクラスをファイルの末尾に追記しています。
class User: """ユーザークラス """ def __init__(self, name): self.name = name class Permission: """パーミッションクラス """ def __init__(self, name): self.name = name
3-way mergeの比較
KDiff3とP4Mergeで前述の3つのファイルをマージしてみます。
KDiff3の場合
KDiff3は0.9.96のcjk対応のものを使っています。
yuja / kdiff3-mq-cjk — Bitbucket
未解決のコンフリクトは、クラス定義とその次の行になります。また、__init__コンストラクタとself.nameへの代入の行は同一とみなされて、自動解決されています。
この場合、未解決のコンフリクト部分でB(local.py)とC(other.py)の内容を単純に選択しても、正しくマージできないため、コピー&ペーストで編集することになります。
P4Mergeの場合
P4Mergeは2015.2を使っています。
Visual Merge and Diff Tools | Perforce
P4Mergeの場合も、未解決のコンフリクト位置と同一な位置の検出はKDiff3と同様でした。
P4Mergeでもこの場合はコピー&ペーストで編集することになります。
ベースを少し工夫した場合の3-way mergeの比較
前述の通り、マージ対象のコードのままではどちらを使っても自動解決できませんでした。
あらかじめ同じモジュールを編集することがわかっているのであれば、ベースのファイル(base.py)に少し手を加えることで、マージツールの差分検出にヒントを与えられます。
base.py(工夫したやつ)
分岐前にあらかじめ、追記する部分にコメントを入れておきます。
class User: """ユーザークラス """ def __init__(self, name): self.name = name # ここにGroupクラス # ここにPermissionクラス
local.py(工夫したbase.pyからの編集)
編集する場合には、base.pyの該当箇所のコメントを削除した上でコードを記述します。この際、追記しない部分のコメントは、残しておくことに注意します。
class User: """ユーザークラス """ def __init__(self, name): self.name = name class Group: """グループクラス """ def __init__(self, name): self.name = name self.users = [] # ここにPermissionクラス
other.py(工夫したbase.pyからの編集)
class User: """ユーザークラス """ def __init__(self, name): self.name = name # ここにGroupクラス class Permission: """パーミッションクラス """ def __init__(self, name): self.name = name
結論
- KDiff3とP4Mergeのどちらでも自動解決できないパターンはある。
- KDiff3の場合、コメント等でマージのヒントになるキーワードを事前に入れておけば、自動解決できることがある。
やっぱりKDiff3を使い続けることになりそう。