Method: Refinement::Changeset.parse_raw_diff
- Defined in:
- lib/refinement/changeset.rb
.parse_raw_diff(diff, repository:, base_revision:) ⇒ Array<FileModification>
Parses the raw diff into FileModification objects
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/refinement/changeset.rb', line 163 def self.parse_raw_diff(diff, repository:, base_revision:) # since we're null separating the chunks (to avoid dealing with path escaping) we have to reconstruct # the chunks into individual diff entries. entries always start with a colon so we can use that to signal if # we're on a new entry parsed_lines = diff.split("\0").each_with_object([]) do |chunk, lines| lines << [] if chunk.start_with?(':') lines.last << chunk end parsed_lines.map do |split_line| # change chunk (letter + optional similarity percentage) will always be the last part of first line chunk change_chunk = split_line[0].split(/\s/).last new_path = Pathname(split_line[2]).freeze if split_line[2] old_path = Pathname(split_line[1]).freeze prior_path = old_path if new_path # new path if one exists, else existing path. new path only exists for rename and copy changed_path = new_path || old_path change_character = change_chunk[0] # returns 0 when a similarity percentage isn't specified by git. _similarity = change_chunk[1..3].to_i FileModification.new( path: changed_path, type: CHANGE_CHARACTERS[change_character], prior_path: prior_path, contents_reader: -> { repo.join(changed_path).read }, prior_contents_reader: lambda { git!('show', "#{base_revision}:#{prior_path || changed_path}", chdir: repository) } ) end end |