#patch #diff #merge

diffy-fork-filenames

是 https://docs.rs/diffy 的分支,允许指定文件名

1 个不稳定版本

0.4.0 2023年6月25日
0.3.0 2023年6月25日

#1286文本处理

35 每月下载
3 crates 中使用

MIT/Apache

145KB
3.5K SLoC

diffy

diffy 的分支,增加了更改文件名的功能。

diffy on crates.io Documentation (latest release) Documentation (master) License License

文件差异查找和操作的工具

许可

本项目可在以下许可协议下使用:Apache 2.0 许可证或 MIT 许可证


lib.rs:

文件差异查找和操作的工具

概述

该库旨在收集用于查找和操作文件差异的工具,灵感来源于 LibXDiffGNU Diffutils。版本控制系统如 Git

当前的 diff 实现基于 Myers' diff 算法

UTF-8 和 Non-UTF-8

该库支持 utf 和非 utf 文本。大多数 API 有两个变体,一个用于处理 utf8 文本(例如 create_patch)和一个用于处理可能不是 utf8 的字节(例如 create_patch_bytes)。

创建补丁

可以通过以下方式创建两个文本之间的 Patch

use diffy::create_patch;

let original = "The Way of Kings\nWords of Radiance\n";
let modified = "The Way of Kings\nWords of Radiance\nOathbringer\n";

let patch = create_patch(original, modified);
#
#

Patch 可以通过其 Display 实现或使用 PatchFormatter 将差异输出为统一格式。

#
#
#
#
#
// Without color
print!("{}", patch);

// With color
let f = PatchFormatter::new().with_color();
print!("{}", f.fmt_patch(&patch));
--- original
+++ modified
@@ -1,2 +1,3 @@
 The Way of Kings
 Words of Radiance
+Oathbringer

应用补丁

一旦你有了 Patch,你就可以将其应用到基图像上以恢复新的文本。每个块将依次应用到基图像上。类似于GNU patch,此实现可以检测补丁中指定的行号是否错误,并将尝试通过从给定位置向前和向后迭代,直到块的所有上下文行与基图像匹配,以找到应用每个块的正确位置。

use diffy::{apply, Patch};

let s = "\
--- a/skybreaker-ideals
+++ b/skybreaker-ideals
@@ -10,6 +10,8 @@
 First:
     Life before death,
     strength before weakness,
     journey before destination.
 Second:
-    I will put the law before all else.
+    I swear to seek justice,
+    to let it guide me,
+    until I find a more perfect Ideal.
";

let patch = Patch::from_str(s).unwrap();

let base_image = "\
First:
    Life before death,
    strength before weakness,
    journey before destination.
Second:
    I will put the law before all else.
";

let expected = "\
First:
    Life before death,
    strength before weakness,
    journey before destination.
Second:
    I swear to seek justice,
    to let it guide me,
    until I find a more perfect Ideal.
";

assert_eq!(apply(base_image, &patch).unwrap(), expected);

执行三次合并

给定一个共同祖先或原始文件 O,两个文件 AB 可以合并在一起,产生一个文件 C,类似于 diff3 执行的三次合并。

    --- A ---
  /           \
 /             \
O               C
 \             /
  \           /
    --- B ---

如果文件 AB 修改了原始文件 O 的不同区域(或以相同的方式修改了同一区域),则可以合并这些文件而不会产生冲突。

use diffy::merge;

let original = "the final empire\nThe Well of Ascension\nThe hero of ages\n";
let a = "The Final Empire\nThe Well of Ascension\nThe Hero of Ages\n";
let b = "The Final Empire\nThe Well of Ascension\nThe hero of ages\n";
let expected = "\
The Final Empire
The Well of Ascension
The Hero of Ages
";

assert_eq!(merge(original, a, b).unwrap(), expected);

如果文件 AB 都修改了原始文件 O 的同一区域(并且这些修改是不同的),则会产生冲突,因为在合并结果中不清楚应该使用哪些修改。

use diffy::merge;

let original = "The Final Empire\nThe Well of Ascension\nThe hero of ages\n";
let a = "The Final Empire\nThe Well of Ascension\nThe Hero of Ages\nSecret History\n";
let b = "The Final Empire\nThe Well of Ascension\nThe hero of ages\nThe Alloy of Law\n";
let expected = "\
The Final Empire
The Well of Ascension
<<<<<<< ours
The Hero of Ages
Secret History
||||||| original
The hero of ages
=======
The hero of ages
The Alloy of Law
>>>>>>> theirs
";

assert_eq!(merge(original, a, b).unwrap_err(), expected);

依赖项

~125–295KB