こんにちは 🙂
プロジェクトで文字列の変更を3-way mergeしなければならない状況があり、Gitのmerge-fileのように動作しつつ、メモリ上で直接文字列をマージできるライブラリが必要でした。
既存のライブラリも調べてみましたが:
- 一時ファイルを必ず使う必要があったり
- Gitと同じ方式で競合を処理しなかったり
- 望むマージ戦略をサポートしていないことが多かったです。
そこで最終的に、libgit2のxdiff(Cコード、Git内部と同一) に対するRustバインディングを書きました。
use threeway_merge::{merge_strings, MergeOptions};
let result = merge_strings(base, ours, theirs, &MergeOptions::default())?;
特徴:
- Gitのすべてのマージアルゴリズムをサポート(Myers、Patience、Histogram など)
- 競合スタイルをサポート(normal、diff3、zdiff3)
- 片側を自動的に優先選択したり、union戦略で変更を結合可能
git merge-fileのテストと100%同一に動作
リンク:
- crates.io: https://crates.io/crates/threeway_merge
- ソースコード: https://github.com/levish0/threeway-merge-rs
他の方にも役立つかもしれないと思い、共有します!
2件のコメント
素晴らしいプロジェクトですね! コードもきれいで、FFI でつなぐときのとても良い実例になりそうです。
ただ、
cargo testを回してみたところ失敗するのですが、私の環境が Ubuntu on WSL2 だからでしょうか。=== COMPREHENSIVE TEST RESULTS ===
Scenarios tested: 12
Total test combinations: 576
Passing tests: 96
Failing tests: 480
Success rate: 16.7%
WSLでは、テストスクリプトが使用するgitの引数が異なっていたと記憶しています