Go implementation of the Patience Diff algorithm.
This library generates line-oriented diffs between source and destination inputs, using the Patience Diff algorithm.
Supports both plain format and Unified format (unidiff).
Plain format:
the
quick
brown
-chicken
+fox
jumps
over
the
+lazy
dog
Unified format (unidiff):
--- a.txt
+++ b.txt
@@ -3,3 +3,3 @@
brown
-chicken
+fox
jumps
@@ -7,2 +7,3 @@
the
+lazy
dog
go get github.com/peter-evans/patience
a := strings.Split(textA, "\n")
b := strings.Split(textB, "\n")
diffs := patience.Diff(a, b)
// Combined diff
diff := patience.DiffText(diffs)
// Split diffs
diffA := patience.DiffTextA(diffs)
diffB := patience.DiffTextB(diffs)
// Unified diff
unidiff := patience.UnifiedDiffText(diffs)
// Unified diff with options
unidiffopts := patience.UnifiedDiffTextWithOptions(
diffs,
UnifiedDiffOptions{
Precontext: 2,
Postcontext: 2,
SrcHeader: "a.txt",
DstHeader: "b.txt",
},
)
Patience Diff is an algorithm credited to Bram Cohen that produces diffs tending to be more human-readable than the common diff algorithm.
The common diff algorithm is based on the longest common subsequence problem. It is credited to Eugene Myers and is the default diff algorithm in Git. While the diffs generated by this algorithm are efficient, in many cases they tend not to correspond to what humans would naturally identify.
Patience Diff, while also relying on computing the longest common subsequence, takes a different approach. It only computes the longest common subsequence of the unique, common elements of both texts. This means that lines that are frequently non-unique, such as those containing a single brace or new line character, are ignored. The result is that distinctive lines, such as function declarations, become the anchor points of commonality between the two texts.
This is an example comparing Patience Diff to the common diff algorithm (Myers).
Patience Diff
#include <stdio.h>
+int fib(int n)
+{
+ if(n > 2)
+ {
+ return fib(n-1) + fib(n-2);
+ }
+ return 1;
+}
+
// Frobs foo heartily
int frobnitz(int foo)
{
int i;
for(i = 0; i < 10; i++)
{
- printf("Your answer is: ");
printf("%d\n", foo);
}
}
-int fact(int n)
-{
- if(n > 1)
- {
- return fact(n-1) * n;
- }
- return 1;
-}
-
int main(int argc, char **argv)
{
- frobnitz(fact(10));
+ frobnitz(fib(10));
}
Common diff (Myers)
#include <stdio.h>
-// Frobs foo heartily
-int frobnitz(int foo)
+int fib(int n)
{
- int i;
- for(i = 0; i < 10; i++)
+ if(n > 2)
{
- printf("Your answer is: ");
- printf("%d\n", foo);
+ return fib(n-1) + fib(n-2);
}
+ return 1;
}
-int fact(int n)
+// Frobs foo heartily
+int frobnitz(int foo)
{
- if(n > 1)
+ int i;
+ for(i = 0; i < 10; i++)
{
- return fact(n-1) * n;
+ printf("%d\n", foo);
}
- return 1;
}
int main(int argc, char **argv)
{
- frobnitz(fact(10));
+ frobnitz(fib(10));
}
- Patience Diff Advantages by Bram Cohen
- Patience Diff, a brief summary by Alfedenzo