Module: Git::Parsers::Diff::Raw Private

Defined in:
lib/git/parsers/diff.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Parser for --raw output (combined with numstat)

Class Method Summary collapse

Class Method Details

.build_file_ref(mode, sha, path) ⇒ Git::FileRef?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Build a FileRef, returning nil if the file doesn't exist on this side



393
394
395
396
397
# File 'lib/git/parsers/diff.rb', line 393

def build_file_ref(mode, sha, path)
  return nil if mode == NULL_MODE || path.nil?

  Git::FileRef.new(mode: mode, sha: sha, path: path)
end

.build_raw_info(parsed, stats) ⇒ Git::DiffFileRawInfo

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Builds a raw diff file info object from parsed metadata and stats



348
349
350
351
352
353
354
# File 'lib/git/parsers/diff.rb', line 348

def build_raw_info(parsed, stats)
  Git::DiffFileRawInfo.new(
    src: build_file_ref(parsed[:modes][0], parsed[:shas][0], parsed[:src_path]),
    dst: build_file_ref(parsed[:modes][1], parsed[:shas][1], parsed[:dst_path]),
    status: parsed[:status], similarity: parsed[:similarity], **stats
  )
end

.extract_paths(paths) ⇒ Array((String, nil), (String, nil))

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Extract source and destination paths from raw output paths



374
375
376
377
378
379
380
381
# File 'lib/git/parsers/diff.rb', line 374

def extract_paths(paths)
  if paths.length == 2
    [Diff.unescape_path(paths[0]), Diff.unescape_path(paths[1])]
  else
    path = Diff.unescape_path(paths[0])
    [path, path]
  end
end

.parse(output, include_dirstat: false) ⇒ Git::DiffResult

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parse combined raw + numstat + shortstat output into DiffResult



280
281
282
283
284
285
286
287
288
289
# File 'lib/git/parsers/diff.rb', line 280

def parse(output, include_dirstat: false)
  raw_lines, numstat_lines, shortstat_line, dirstat_lines = split_sections(output, include_dirstat)
  numstat_map = Numstat.parse_as_map(numstat_lines, include_binary: true)

  Diff.build_result(
    files: raw_lines.map { |line| parse_raw_line(line, numstat_map) },
    shortstat: Diff.parse_shortstat(shortstat_line),
    dirstat: include_dirstat ? Diff.parse_dirstat(dirstat_lines) : nil
  )
end

.parse_raw_line(line, numstat_map) ⇒ Git::DiffFileRawInfo

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parse a single --raw output line



318
319
320
321
322
323
# File 'lib/git/parsers/diff.rb', line 318

def parse_raw_line(line, numstat_map)
  parsed = parse_raw_line_parts(line)
  stats = numstat_map.fetch(parsed[:dst_path] || parsed[:src_path],
                            { insertions: 0, deletions: 0, binary: false })
  build_raw_info(parsed, stats)
end

.parse_raw_line_parts(line) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parses the fields from a raw diff line



331
332
333
334
335
336
337
338
# File 'lib/git/parsers/diff.rb', line 331

def parse_raw_line_parts(line)
  parts = line[1..].split(/\s+/, 5)
  status_char, *paths = parts[4].split("\t")
  status, similarity = parse_status(status_char)
  src_path, dst_path = extract_paths(paths)
  { modes: parts[0..1], shas: parts[2..3], status: status,
    similarity: similarity, src_path: src_path, dst_path: dst_path }
end

.parse_status(status_char) ⇒ Array(Symbol, (Integer, nil))

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parse status character and optional similarity percentage



362
363
364
365
366
# File 'lib/git/parsers/diff.rb', line 362

def parse_status(status_char)
  letter = status_char[0]
  similarity = status_char.length > 1 ? status_char[1..].to_i : nil
  [STATUS_MAP.fetch(letter, :unknown), similarity]
end

.split_sections(output, include_dirstat) ⇒ Array(Array<String>, Array<String>, (String, nil), Array<String>)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Split output into raw, numstat, shortstat, and dirstat sections



299
300
301
302
303
304
305
306
307
308
# File 'lib/git/parsers/diff.rb', line 299

def split_sections(output, include_dirstat)
  lines = output.split("\n").reject(&:empty?)
  raw_lines, non_raw_lines = lines.partition { |l| l.start_with?(':') }
  shortstat_index = non_raw_lines.index { |l| l.match?(/^\s*\d+\s+files?\s+changed/) }

  return [raw_lines, non_raw_lines, nil, []] unless shortstat_index

  [raw_lines, non_raw_lines[0...shortstat_index], non_raw_lines[shortstat_index],
   include_dirstat ? non_raw_lines[(shortstat_index + 1)..] : []]
end