Plain diff
Give Rift two files and it writes a unified diff to standard output, the same format as diff -u.
rift a.sql b.sql > changes.patch
The heap Rift holds never passes the limit you set with --mem. The default is 256 MiB.
Here is the start of a diff of two generated SQL dumps. The files are 64 MiB each, and a change starts at about one line in a thousand.
$ rift a.sql b.sql --- a.sql+++ b.sql@@ -380,7 +380,6 @@ INSERT INTO public.orders (id, customer_id, status, amount, note) VA… 381 178722 cancelled 2930.54 wmojdqnzik INSERT INTO public.orders (id, customer_id, status, amount, note) VA…-383 668107 shipped 5325.74 zu INSERT INTO public.orders (id, customer_id, status, amount, note) VA… 385 359182 cancelled 475.15 ztbyhdlmxk INSERT INTO public.orders (id, customer_id, status, amount, note) VA…@@ -1279,6 +1278,7 @@ 1277 990810 cancelled 3466.36 qppoqa INSERT INTO public.orders (id, customer_id, status, amount, note) VA… 1279 877409 new 9427.22 ivpjtbhdno+383 668107 shipped 5325.74 zu INSERT INTO public.orders (id, customer_id, status, amount, note) VA… 1281 232076 cancelled 3547.41 lkkqfp INSERT INTO public.orders (id, customer_id, status, amount, note) VA…
Apply the diff
The diff is an edit script. Applied to the first file with patch, it gives the second file byte for byte, line endings and a missing final newline included.
$ rift a.sql b.sql > changes.patch $ patch a.sql changes.patch $ cmp a.sql b.sql && echo identical patching file a.sql identical
Peak heap and time
--stats prints the peak heap, the time, the approximate regions and the moved blocks to standard error, so the diff on standard output stays clean:
$ rift --stats a.sql b.sql > changes.patch peak heap 78.6 MiB of 256.0 MiB (82396678 bytes) time 0.69 s approx 0 segments, 0 lines in a and b moved 62 blocks, 2737 lines a 21557..21560 b 22434..22437 a 25038..25048 b 26389..26399 a 27627..27952 b 28206..28531 a 36864..36874 b 36680..36690 a 48226..48235 b 49457..49466 a 50776..50780 b 50896..50900 a 59441..59445 b 61396..61400 a 65493..65499 b 65178..65184 a 99590..99595 b 99830..99835 a 110203..110209 b 111213..111219 ... and 52 more
Rift marks a region it could not align within the budget as approximate: the unified diff puts approx: and the reason after the closing @@ of the hunk header, where diff -p puts a function name, and patch ignores it. Here the count is 0. An approximate hunk is still correct, only coarser than it could be. The reasons:
| Reason in the header | What it means |
|---|---|
too many changes among repeated lines to align them exactly | No line in the region occurs once in each file, and the search for the smallest diff hit its cost limit. |
found no line here that occurs once in each file, so there is nothing to align on | The region was too large to diff in one piece, and Rift found no line to cut it at. |
too large to align within --mem; a larger --mem may help | The region ran out of its share of the budget. |
--stats counts the approximate segments for each reason. Two files that share no line come out as one deletion and one insertion without the mark: with nothing in common, that is the smallest diff.
What it does not promise
The diff is not minimal. Like patience diff in git, Rift can show a change as larger than the smallest possible one. Correctness is the promise: the output always rebuilds the second file from the first.