samg / diffy

Easy Diffing in Ruby
http://rubygems.org/gems/diffy
MIT License
1.26k stars 103 forks source link

Use rugged for diffing #124

Open Earlopain opened 11 months ago

Earlopain commented 11 months ago

This is a proof of concept.

Diffy currently uses a subprocesses to obtain a diff. This instead uses libgit through the gem rugged. I have opted to ignore backwards compatibility for this. There is probably a way you can have the current mode and this coexist but that would have introduced a bunch more complexity (I also don't see why you'd want to maintain both versions anyways). Almost all tests are passing, except a few outliers I couldn't quite figure out myself.

This version is faster since it doesn't have to spawn subprocesses and is easier to install and deploy because rugged comes with everything it needs out of the box.

Connects to #123

Here is a monkeypatch to make use of this today. It's lacking quite a few features normally found in the gem but it works for my specific usecase and can easily extended.

require "rugged"

module DiffyNoSubprocess
  def diff
    @diff ||= Rugged::Patch.from_strings(@string1, @string2, context_lines: 10_000).to_s.force_encoding("UTF-8")
  end

  def each
    lines = diff.split("\n").drop(5).map { |line| "#{line}\n" }

    if block_given?
      lines.each { |line| yield line }
    else
      lines.to_enum
    end
  end
end

Diffy::Diff.prepend DiffyNoSubprocess