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

Parameters:

  • mode (String)

    file mode

  • sha (String)

    file SHA

  • path (String, nil)

    file path

Returns:



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

Parameters:

  • parsed (Hash)

    parsed metadata from #parse_raw_line_parts

  • stats (Hash)

    insertion, deletion, and binary information

Returns:



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

Parameters:

  • paths (Array<String>)

    paths array

Returns:

  • (Array((String, nil), (String, nil)))

    [src_path, dst_path]



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

Parameters:

  • output (String)

    combined output

  • include_dirstat (Boolean) (defaults to: false)

    whether dirstat output is expected

Returns:



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

Parameters:

  • line (String)

    a single raw output line

  • numstat_map (Hash<String, Hash>)

    path to stats mapping

Returns:



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

Parameters:

  • line (String)

    a single raw output line

Returns:

  • (Hash)

    parsed metadata for one raw diff entry



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

Parameters:

  • status_char (String)

    e.g., 'M', 'A', 'R075'

Returns:

  • (Array(Symbol, (Integer, nil)))

    [status, similarity]



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

Parameters:

  • output (String)

    combined output

  • include_dirstat (Boolean)

    whether to expect dirstat section

Returns:

  • (Array(Array<String>, Array<String>, (String, nil), Array<String>))


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