// Package diff implements line oriented diffs, similar to the ancient // Unix diff command. // // The current implementation is just a wrapper around Sergi's // go-diff/diffmatchpatch library, which is a go port of Neil // Fraser's google-diff-match-patch code package diff import ( "bytes" "time" "github.com/sergi/go-diff/diffmatchpatch" ) // Do computes the (line oriented) modifications needed to turn the src // string into the dst string. The underlying algorithm is Meyers, // its complexity is O(N*d) where N is min(lines(src), lines(dst)) and d // is the size of the diff. func Do(src, dst string) (diffs []diffmatchpatch.Diff) { // the default timeout is time.Second which may be too small under heavy load return DoWithTimeout(src, dst, time.Hour) } // DoWithTimeout computes the (line oriented) modifications needed to turn the src // string into the dst string. The `timeout` argument specifies the maximum // amount of time it is allowed to spend in this function. If the timeout // is exceeded, the parts of the strings which were not considered are turned into // a bulk delete+insert and the half-baked suboptimal result is returned at once. // The underlying algorithm is Meyers, its complexity is O(N*d) where N is // min(lines(src), lines(dst)) and d is the size of the diff. func DoWithTimeout (src, dst string, timeout time.Duration) (diffs []diffmatchpatch.Diff) { dmp := diffmatchpatch.New() dmp.DiffTimeout = timeout wSrc, wDst, warray := dmp.DiffLinesToRunes(src, dst) diffs = dmp.DiffMainRunes(wSrc, wDst, false) diffs = dmp.DiffCharsToLines(diffs, warray) return diffs } // Dst computes and returns the destination text. func Dst(diffs []diffmatchpatch.Diff) string { var text bytes.Buffer for _, d := range diffs { if d.Type != diffmatchpatch.DiffDelete { text.WriteString(d.Text) } } return text.String() } // Src computes and returns the source text func Src(diffs []diffmatchpatch.Diff) string { var text bytes.Buffer for _, d := range diffs { if d.Type != diffmatchpatch.DiffInsert { text.WriteString(d.Text) } } return text.String() }