前回はiPhone メモアプリの挙動とマージの難しさを確認しました。
今回は実際に JavaDiffUtils を使い、テキスト差分の取得と適用の基本を押さえます。そして、次回の 3-way-merge 実装につなげます。
まずは、今回のマージ機能の要件を整理します。
要件の整理
今回のマージ機能はメモアプリでの利用を前提にしています。Git等のソース管理で行われているマージとは要件が異なります。
- ユーザ操作なしで自動マージする
- コンフリクト時は両方の修正版を残す
要件の例

このように、eとf の両方の変更を残すことで、必要な情報が失われるのを防ぎます。最終的な判断はユーザに委ねますが、情報が消えるよりはマシという方針です。
JavaDiffUtils の基本
使い方はとても簡単です。
kotlin
val base = listOf("AAA", "BBB", "CCC")
val local = listOf("AAA", "BeB", "CCC")
val patch = DiffUtils.diff(base, local)
DiffUtils.diff() を実行するだけで、差分を算出してくれます。
patch の中身を見てみます。
patch:
deltas:
0:
type: CHANGE <-- 他に、INSERT, DELETEがある
source:
position: 1 <-- 修正元の行番号(0始まり)
lines: [BBB] <-- 修正前の内容
target:
position: 1
lines: [BeB] <-- 修正後の内容
- type: CHANGE(変更)、INSERT(追加)とDELETE(削除)がある
- source: 修正前の行情報(位置と内容)
- target: 修正後の行情報

さらに、patch.applyTo(base) を使えば、差分を元文章に適用できます。便利ですね。
val applied = patch.applyTo(base)
println(applied)
// AAA
// BeB
// CCC
注意点として、deltas は修正行番号で管理しているため、base を変更するとパッチが適用できずにエラーになることがあります。
次回予告
ここまでで、JavaDiffUtils を使った差分取得と適用の基本がわかりました。次回はこの仕組みを使い、自動で両方の変更を残す 3-way-merge を実装していきます。
コメントを残す