class RJGit::Plumbing::ApplyPatchToIndex

Constants

ADD
COPY
DELETE
MODIFY
RENAME

Public Class Methods

diffs_to_patch(diffs) click to toggle source

Take the result of RJGit::Porcelain.diff with options = true and return a patch String

# File lib/rjgit.rb, line 447
def self.diffs_to_patch(diffs)
  diffs.inject(""){|result, diff| result << diff[:patch]}
end
new(repository, patch, ref = Constants::HEAD) click to toggle source
Calls superclass method RJGit::Plumbing::Index::new
# File lib/rjgit.rb, line 451
def initialize(repository, patch, ref = Constants::HEAD)
  super(repository)
  @ref   = ref
  @patch = Patch.new
  @patch.parse(ByteArrayInputStream.new(patch.to_java_bytes))
  raise_patch_apply_error unless @patch.getErrors.isEmpty()
  @current_tree = Commit.find_head(@jrepo, ref).tree
end

Public Instance Methods

build_map() click to toggle source
# File lib/rjgit.rb, line 464
def build_map
  raise_patch_apply_error if @patch.getFiles.isEmpty()
  @patch.getFiles.each do |file_header|
    case file_header.getChangeType
    when ADD
      add(file_header.getNewPath, apply('', file_header))
    when MODIFY
      add(file_header.getOldPath, apply(getData(file_header.getOldPath), file_header))
    when DELETE
      delete(file_header.getOldPath)
    when RENAME
      delete(file_header.getOldPath)
      add(file_header.getNewPath, getData(file_header.getOldPath))
    when COPY
      add(file_header.getNewPath, getData(file_header.getOldPath))
    end
  end
  @treemap
end
commit(message, author, parents = nil, force = false) click to toggle source
Calls superclass method RJGit::Plumbing::Index#commit
# File lib/rjgit.rb, line 460
def commit(message, author, parents = nil, force = false)
  super(message, author, parents, @ref, force)
end
new_tree() click to toggle source

Build the new tree based on the patch, but don’t commit it Return the String object id of the new tree, and an Array of affected paths

# File lib/rjgit.rb, line 486
def new_tree
  map = build_map
  return ObjectId.to_string(build_new_tree(map, @ref)), map.keys
end

Private Instance Methods

apply(original, file_header) click to toggle source
# File lib/rjgit.rb, line 509
def apply(original, file_header)
  newLines = original.lines
  file_header.getHunks.each do |hunk|
    length = hunk.getEndOffset - hunk.getStartOffset
    buffer_text = hunk.getBuffer.to_s.slice(hunk.getStartOffset, length)
    pos = 0
    buffer_text.each_line do |hunk_line|
      case hunk_line[0]
        when ' '
          hunk_sanity_check(hunk, hunk_line, pos, newLines)
          pos += 1
        when '-'
          if hunk.getNewStartLine == 0
            newLines = []
          else
            hunk_sanity_check(hunk, hunk_line, pos, newLines)
            newLines.slice!(hunk.getNewStartLine - 1 + pos)
          end
        when '+'
          newLines.insert(hunk.getNewStartLine - 1 + pos, hunk_line[1..-1])
          pos += 1
      end
    end
  end
  newLines.join
end
getData(path) click to toggle source
# File lib/rjgit.rb, line 497
def getData(path)
  begin
    (@current_tree / path).data
  rescue NoMethodError
    raise_patch_apply_error
  end
end
hunk_sanity_check(hunk, hunk_line, pos, newLines) click to toggle source
# File lib/rjgit.rb, line 505
def hunk_sanity_check(hunk, hunk_line, pos, newLines)
  raise_patch_apply_error unless newLines[hunk.getNewStartLine - 1 + pos] == hunk_line[1..-1]
end
raise_patch_apply_error() click to toggle source
# File lib/rjgit.rb, line 493
def raise_patch_apply_error
  raise ::RJGit::PatchApplyException.new('Patch failed to apply')
end