10 ポイント 投稿者 levish 2025-09-05 | 2件のコメント | WhatsAppで共有

こんにちは 🙂

プロジェクトで文字列の変更を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%同一に動作

リンク:

他の方にも役立つかもしれないと思い、共有します!

2件のコメント

 
jamiecha 2025-09-06

素晴らしいプロジェクトですね! コードもきれいで、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%

 
levish 2025-09-06

WSLでは、テストスクリプトが使用するgitの引数が異なっていたと記憶しています