class Git::Diff::FullDiffParser

A private parser class to process the output of ‘git diff` @api private

Public Class Methods

new(base, patch_text) click to toggle source
# File lib/git/diff.rb, line 126
def initialize(base, patch_text)
  @base = base
  @patch_text = patch_text
  @final_files = {}
  @current_file_data = nil
  @defaults = { mode: '', src: '', dst: '', type: 'modified', binary: false }
end

Public Instance Methods

parse() click to toggle source
# File lib/git/diff.rb, line 134
def parse
  @patch_text.split("\n").each { |line| process_line(line) }
  @final_files.map { |filename, data| [filename, DiffFile.new(@base, data)] }
end

Private Instance Methods

append_to_current_file(line) click to toggle source
# File lib/git/diff.rb, line 155
def append_to_current_file(line)
  return unless @current_file_data

  parse_index_line(line)
  parse_file_mode_line(line)
  check_for_binary(line)

  @current_file_data[:patch] << "\n#{line}"
end
check_for_binary(line) click to toggle source
# File lib/git/diff.rb, line 180
def check_for_binary(line)
  @current_file_data[:binary] = true if line.match?(/^Binary files /)
end
parse_file_mode_line(line) click to toggle source
# File lib/git/diff.rb, line 173
def parse_file_mode_line(line)
  return unless (match = line.match(/^([[:alpha:]]*?) file mode (......)/))

  @current_file_data[:type] = match[1]
  @current_file_data[:mode] = match[2]
end
parse_index_line(line) click to toggle source
# File lib/git/diff.rb, line 165
def parse_index_line(line)
  return unless (match = line.match(/^index ([0-9a-f]{4,40})\.\.([0-9a-f]{4,40})( ......)*/))

  @current_file_data[:src] = match[1]
  @current_file_data[:dst] = match[2]
  @current_file_data[:mode] = match[3].strip if match[3]
end
process_line(line) click to toggle source
# File lib/git/diff.rb, line 141
def process_line(line)
  if (new_file_match = line.match(%r{\Adiff --git ("?)a/(.+?)\1 ("?)b/(.+?)\3\z}))
    start_new_file(new_file_match, line)
  else
    append_to_current_file(line)
  end
end
start_new_file(match, line) click to toggle source
# File lib/git/diff.rb, line 149
def start_new_file(match, line)
  filename = Git::EscapedPath.new(match[2]).unescape
  @current_file_data = @defaults.merge({ patch: line, path: filename })
  @final_files[filename] = @current_file_data
end