blog

テキストをマージしたい(2) – JavaDiffUtils を試す

前回は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 を実装していきます。

【広告】

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です