Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/peter-evans/patience

Go implementation of the Patience Diff algorithm
https://github.com/peter-evans/patience

diff diff-algorithm go golang lcs line-oriented longest-common-subsequence patience patiencediff unidiff unified-diff unified-format

Last synced: 2 months ago
JSON representation

Go implementation of the Patience Diff algorithm

Awesome Lists containing this project

README

        

# patience

[![CI](https://github.com/peter-evans/patience/actions/workflows/ci.yml/badge.svg)](https://github.com/peter-evans/patience/actions/workflows/ci.yml)
[![GoReportCard](https://goreportcard.com/badge/github.com/peter-evans/patience)](https://goreportcard.com/report/github.com/peter-evans/patience)
[![GoDoc](https://godoc.org/github.com/peter-evans/patience?status.svg)](https://godoc.org/github.com/peter-evans/patience)

Go implementation of the Patience Diff algorithm.

This library generates line-oriented diffs between source and destination inputs, using the Patience Diff algorithm.

## Features

Supports both plain format and [Unified format](https://en.wikipedia.org/wiki/Diff#Unified_format) (unidiff).

Plain format:
```diff
the
quick
brown
-chicken
+fox
jumps
over
the
+lazy
dog
```

Unified format (unidiff):

```diff
--- a.txt
+++ b.txt
@@ -3,3 +3,3 @@
brown
-chicken
+fox
jumps
@@ -7,2 +7,3 @@
the
+lazy
dog
```

## Installation

```sh
go get github.com/peter-evans/patience
```

## Usage

```go
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",
},
)
```

## About

Patience Diff is an algorithm credited to [Bram Cohen](https://bramcohen.livejournal.com/73318.html) 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](https://en.wikipedia.org/wiki/Longest_common_subsequence_problem) problem.
It is credited to [Eugene Myers](http://www.xmailserver.org/diff2.pdf) 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
```diff
#include

+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)
```diff
#include

-// 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));
}
```

## References

- [Patience Diff Advantages](https://bramcohen.livejournal.com/73318.html) by Bram Cohen
- [Patience Diff, a brief summary](https://alfedenzo.livejournal.com/170301.html) by Alfedenzo