class MetaCommit::Git::Repo

Rugged::Repository wrapper @attr [Rugged::Repository] repo

Constants

DIFF_OPTIONS
FILE_NOT_EXISTS_OID
INDEX_DIFF_OPTIONS

Attributes

repo[RW]

Public Class Methods

new(repo_path) click to toggle source

@param [String] repo_path

# File lib/meta_commit/git/repo.rb, line 15
def initialize(repo_path)
  begin
    @repo = Rugged::Repository.new(repo_path)
  rescue Rugged::OSError
    raise MetaCommit::Errors::MissingRepoError
  rescue Rugged::RepositoryError
    raise MetaCommit::Errors::MissingRepoError
  end
end

Public Instance Methods

commit_of_tag(search_tag) click to toggle source

@param [String] search_tag @return [Rugged::Commit, nil]

# File lib/meta_commit/git/repo.rb, line 127
def commit_of_tag(search_tag)
  @repo.tags.each do |tag|
    return tag.target if tag.name == search_tag
  end
end
diff(left, right, options) click to toggle source

Proxy to Rugged::Repository#diff @param [Object] left @param [Object] right @param [Hash] options @return [Rugged::Diff::Delta]

# File lib/meta_commit/git/repo.rb, line 54
def diff(left, right, options)
  @repo.diff(left, right, options)
end
diff_with_optimized_lines(left, right) { |old_file, new_file, patch, line| ... } click to toggle source

Iterates over optimized lines in diff @param [Object] left @param [Object] right @yield [old_file_path, new_file_path, patch, line] @return [Object]

# File lib/meta_commit/git/repo.rb, line 63
def diff_with_optimized_lines(left, right)
  diff = @repo.diff(left, right, DIFF_OPTIONS)
  diff.deltas.zip(diff.patches).each do |delta, patch|
    lines = organize_lines(delta, patch)
    lines.each do |line|
      yield(delta.old_file[:path], delta.new_file[:path], patch, line)
    end
  end
end
dir() click to toggle source

@return [String] directory of repository

# File lib/meta_commit/git/repo.rb, line 121
def dir
  @repo.path.reverse.sub('/.git'.reverse, '').reverse
end
get_blob_at(revision, path, default = nil) click to toggle source

@param [String] revision commit hash @param [String] path @param [String] default value to be returned if error appears

# File lib/meta_commit/git/repo.rb, line 96
def get_blob_at(revision, path, default = nil)
  blob = @repo.blob_at(revision, path)
  return blob.content unless blob.nil?
  default
end
get_content_of(rel_repo_file_path, default = nil) click to toggle source

@param [String] rel_repo_file_path file path relative to repository root @param [String] default value to be returned if error appears @return [String] file content or default value

# File lib/meta_commit/git/repo.rb, line 105
def get_content_of(rel_repo_file_path, default = nil)
  absolute_file_path = dir + rel_repo_file_path
  begin
    content = open(absolute_file_path).read
  rescue Errno::ENOENT
    content = default
  end
  content
end
index_diff(options) click to toggle source

Proxy to Rugged::Index#diff @param [Hash] options @return [Rugged::Diff::Delta]

# File lib/meta_commit/git/repo.rb, line 89
def index_diff(options)
  @repo.index.diff(@repo.head.target.tree, options)
end
index_diff_with_optimized_lines() { |old_file, new_file, patch, line| ... } click to toggle source

Iterates over optimized lines in index diff @yield [old_file_path, new_file_path, patch, line] @return [Object]

# File lib/meta_commit/git/repo.rb, line 76
def index_diff_with_optimized_lines
  diff = index_diff(INDEX_DIFF_OPTIONS)
  diff.deltas.zip(diff.patches).each do |delta, patch|
    lines = organize_lines(delta, patch)
    lines.each do |line|
      yield(delta.old_file[:path], delta.new_file[:path], patch, line)
    end
  end
end
last_commit_oid() click to toggle source

@return [String] last commit oid

# File lib/meta_commit/git/repo.rb, line 134
def last_commit_oid
  @repo.last_commit.oid
end
path() click to toggle source

@return [String] path to .git folder of repository

# File lib/meta_commit/git/repo.rb, line 116
def path
  @repo.path
end
walk_by_commits() { |previous_commit, current_commit| ... } click to toggle source

Starts commit walker and yields following commits for easier iteration @yield [previous_commit, current_commit]

# File lib/meta_commit/git/repo.rb, line 35
def walk_by_commits
  walker = Rugged::Walker.new(@repo)
  walker.sorting(Rugged::SORT_REVERSE)
  walker.push(@repo.last_commit.oid)
  previous_commit = nil
  walker.each do |current_commit|
    # skip first commit
    previous_commit = current_commit if previous_commit.nil?
    next if previous_commit == current_commit
    yield(previous_commit, current_commit)
    previous_commit = current_commit
  end
end
walker() click to toggle source

@return [Rugged::Walker] commit iterator

# File lib/meta_commit/git/repo.rb, line 26
def walker
  walker = Rugged::Walker.new(@repo)
  walker.sorting(Rugged::SORT_REVERSE)
  walker.push(@repo.last_commit.oid)
  walker
end

Private Instance Methods

organize_lines(delta, patch) click to toggle source

@param [Object] delta @param [Object] patch @return [Array<MetaCommit::Models::Line>]

# File lib/meta_commit/git/repo.rb, line 141
def organize_lines(delta, patch)
  lines_to_walk = []
  # if whole file was changed examine one time only
  whole_file_changed = (delta.old_file[:oid] == FILE_NOT_EXISTS_OID) || (delta.new_file[:oid] == FILE_NOT_EXISTS_OID)
  skip_walking = false
  skip_next_line = false
  patch.hunks.each_with_index do |hunk|
    break if skip_walking
    hunk.lines.each_with_index do |line, line_index|
      break if skip_walking

      if skip_next_line
        skip_next_line = false
        next
      end

      next_line = hunk.lines[line_index + 1]
      is_replace_change = (line.deletion?) && (!next_line.nil? && next_line.addition?) && (line.old_lineno && next_line.new_lineno)

      line_to_walk = MetaCommit::Models::Line.new
      if is_replace_change
        line_to_walk.line_origin = :replace
        line_to_walk.old_lineno = line.old_lineno
        line_to_walk.new_lineno = next_line.new_lineno
        line_to_walk.content_offset = next_line.content_offset
      else
        line_to_walk.line_origin = line.line_origin
        line_to_walk.old_lineno = line.old_lineno
        line_to_walk.new_lineno = line.new_lineno
        line_to_walk.content_offset = line.content_offset
      end
      if is_replace_change
        skip_next_line = true
      end
      lines_to_walk.push(line_to_walk)

      skip_walking = true if whole_file_changed
    end
  end
  lines_to_walk
end