module GitCrecord::Diff

Public Class Methods

create(reverse: false, untracked: false) click to toggle source
# File lib/git_crecord/diff.rb, line 8
def self.create(reverse: false, untracked: false)
  GitCrecord::Git.status.lines.map do |file_status|
    status = file_status[reverse ? 0 : 1].downcase
    filename = file_status.chomp[3..-1]
    next if status == ' ' || status == '?' && !untracked

    method = "handle_status_#{status}"
    send(method, filename, reverse: reverse) if respond_to?(method)
  end.compact
end
file_encoding(filename) click to toggle source
# File lib/git_crecord/diff.rb, line 72
def self.file_encoding(filename)
  `file --mime-encoding #{filename}`.split(': ', 2)[1].chomp
end
file_lines(filename) click to toggle source
# File lib/git_crecord/diff.rb, line 76
def self.file_lines(filename)
  return [[], 'empty'] if ::File.size(filename).zero?

  encoding = file_encoding(filename)
  return [[], 'binary'] if encoding == 'binary'

  [::File.open(filename, "r:#{encoding}", &:readlines), nil]
end
handle_line(file, line) click to toggle source

o ' ' = unmodified o M = modified o A = added o D = deleted o R = renamed o C = copied o U = updated but unmerged

# File lib/git_crecord/diff.rb, line 59
def self.handle_line(file, line)
  line.chomp!
  if hunk_start?(line)
    file << line
  else
    file.add_hunk_line(line)
  end
end
handle_status_?(filename, **_) click to toggle source
# File lib/git_crecord/diff.rb, line 38
def self.handle_status_?(filename, **_)
  File.new(filename, filename, type: :untracked).tap do |file|
    lines, err = file_lines(filename)
    if lines.empty?
      file.make_empty(err)
    else
      file << "@@ -0,0 +1,#{lines.size} @@"
      lines.each { |line| file.add_hunk_line("+#{line.chomp}") }
    end
    file.selected = false
  end
end
handle_status_a(filename, reverse: false) click to toggle source
# File lib/git_crecord/diff.rb, line 28
def self.handle_status_a(filename, reverse: false)
  file = File.new(filename, filename, type: :new, reverse: reverse)
  diff_lines = Git.diff(filename: filename, staged: reverse).lines[5..-1]
  file.make_empty if diff_lines.nil?
  (diff_lines || []).each do |line|
    handle_line(file, line)
  end
  file
end
handle_status_m(filename, reverse: false) click to toggle source
# File lib/git_crecord/diff.rb, line 19
def self.handle_status_m(filename, reverse: false)
  file = File.new(filename, filename, type: :modified, reverse: reverse)
  diff_lines = Git.diff(filename: filename, staged: reverse).lines[4..-1]
  diff_lines.each do |line|
    handle_line(file, line)
  end
  file
end
hunk_start?(line) click to toggle source
# File lib/git_crecord/diff.rb, line 68
def self.hunk_start?(line)
  line.start_with?('@@')
end