Module: GitCrecord::Diff

Defined in:
lib/git_crecord/diff.rb,
lib/git_crecord/diff/file.rb,
lib/git_crecord/diff/hunk.rb,
lib/git_crecord/diff/line.rb,
lib/git_crecord/diff/difference.rb

Defined Under Namespace

Classes: Difference, File, Hunk, Line, PseudoLine

Class Method Summary collapse

Class Method Details

.create(reverse: false, untracked: false) ⇒ Object



8
9
10
11
12
13
14
15
16
17
# 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) ⇒ Object



72
73
74
# 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) ⇒ Object



76
77
78
79
80
81
82
83
# 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) ⇒ Object

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



59
60
61
62
63
64
65
66
# 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, **_) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
41
42
43
44
45
46
47
48
49
# 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) ⇒ Object



28
29
30
31
32
33
34
35
36
# 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) ⇒ Object



19
20
21
22
23
24
25
26
# 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) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/git_crecord/diff.rb', line 68

def self.hunk_start?(line)
  line.start_with?('@@')
end