class Git::Diff::FullDiffParser
Private parser for โgit diff` output
@example Parse a diff patch
parser = Git::Diff::FullDiffParser.new(base, patch_text) files = parser.parse
@api private
Public Class Methods
Source
# File lib/git/diff.rb, line 404 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
Creates a new FullDiffParser
@param base [Git::Repository] the git repository
@param patch_text [String] the raw โgit diff` output to parse
@return [void]
Public Instance Methods
Source
# File lib/git/diff.rb, line 417 def parse @patch_text.split("\n").each { |line| process_line(line) } @final_files.map { |filename, data| [filename, DiffFile.new(@base, data)] } end
Parses the diff text into a list of filename/DiffFile pairs
@return [Array<Array(String, Git::Diff::DiffFile)>] list of
`[filename, DiffFile]` pairs
Private Instance Methods
Source
# File lib/git/diff.rb, line 458 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
Appends a diff line to the current fileโs accumulated data
@param line [String] a diff line to append
@return [void]
Source
# File lib/git/diff.rb, line 501 def check_for_binary(line) @current_file_data[:binary] = true if line.match?(/^Binary files /) end
Marks the current file as binary if this is a binary diff line
@param line [String] a diff line to check for the binary file marker
@return [void]
Source
# File lib/git/diff.rb, line 488 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
Parses a file mode line to extract the change type and file mode
@param line [String] a diff line that may be a file mode line
@return [void]
Source
# File lib/git/diff.rb, line 474 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
Parses an index line to extract source and destination blob SHAs
@param line [String] a diff line that may be an index line
@return [void]
Source
# File lib/git/diff.rb, line 430 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
Dispatches a single diff line to the appropriate handler
@param line [String] a line from the diff output
@return [void]
Source
# File lib/git/diff.rb, line 446 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
Starts tracking a new file from a diff header line
@param match [MatchData] the regex match from the diff header line
@param line [String] the original diff header line
@return [void]