class RepositoryMerger::MonoRepository

Attributes

current_checked_out_commit_id[RW]

Public Class Methods

new(_path) click to toggle source
Calls superclass method
# File lib/repository_merger/mono_repository.rb, line 8
def initialize(_path)
  super
  configure
end

Public Instance Methods

create_or_update_branch(branch_name, commit_id:) click to toggle source
# File lib/repository_merger/mono_repository.rb, line 39
def create_or_update_branch(branch_name, commit_id:)
  if branch_for(branch_name)
    # `rugged_repo.branches.create` with master branch fails with error:
    # cannot force update branch 'master' as it is the current HEAD of the repository. (Rugged::ReferenceError)
    rugged_repo.references.update("refs/heads/#{branch_name}", commit_id)
  else
    rugged_repo.branches.create(branch_name, commit_id)
  end
end
import_commit(original_commit, new_parents:, subdirectory:, message: nil) click to toggle source
# File lib/repository_merger/mono_repository.rb, line 13
def import_commit(original_commit, new_parents:, subdirectory:, message: nil)
  checkout_contents_if_needed(new_parents.first) unless new_parents.empty?

  stage_contents_of(original_commit, subdirectory: subdirectory)

  create_commit_with_metadata_of(
    original_commit,
    new_parent_ids: new_parents.map(&:id),
    message: message
  )
end
import_tag(original_tag, new_commit_id:, new_tag_name:) click to toggle source
# File lib/repository_merger/mono_repository.rb, line 25
def import_tag(original_tag, new_commit_id:, new_tag_name:)
  # This is to suppress warning messages
  # `warning: Using the last argument as keyword parameters is deprecated`
  # from rugged gem until a fixed version is released.
  # https://github.com/libgit2/rugged/pull/840
  if original_tag.annotation
    rugged_repo.tags.create(new_tag_name, new_commit_id, **original_tag.annotation)
  else
    rugged_repo.tags.create(new_tag_name, new_commit_id)
  end

  tag_for(new_tag_name)
end

Private Instance Methods

checkout_contents_if_needed(commit) click to toggle source
# File lib/repository_merger/mono_repository.rb, line 57
def checkout_contents_if_needed(commit)
  return if empty_commit_for_debug?
  return if commit.id == current_checked_out_commit_id
  commit.checkout_contents
  @current_checked_out_commit_id = commit.id
end
configure() click to toggle source
# File lib/repository_merger/mono_repository.rb, line 51
def configure
  rugged_repo.config['core.ignorecase'] = false
end
create_commit_with_metadata_of(original_commit, new_parent_ids:, message:) click to toggle source
# File lib/repository_merger/mono_repository.rb, line 85
def create_commit_with_metadata_of(original_commit, new_parent_ids:, message:)
  original_rugged_commit = original_commit.rugged_commit

  new_commit_id = Rugged::Commit.create(rugged_repo, {
    message: message || original_rugged_commit.message,
    committer: original_rugged_commit.committer,
    author: original_rugged_commit.author,
    tree: empty_commit_for_debug? ? empty_tree.oid : rugged_repo.index.write_tree,
    parents: new_parent_ids
  })

  @current_checked_out_commit_id = new_commit_id

  commit_for(new_commit_id)
end
empty_commit_for_debug?() click to toggle source
# File lib/repository_merger/mono_repository.rb, line 101
def empty_commit_for_debug?
  ENV['REPO_MERGER_IMPORT_AS_EMPTY_COMMITS']
end
empty_tree() click to toggle source
# File lib/repository_merger/mono_repository.rb, line 105
def empty_tree
  @empty_tree ||= Rugged::Tree.empty(rugged_repo)
end
stage_contents_of(original_commit, subdirectory:) click to toggle source
# File lib/repository_merger/mono_repository.rb, line 64
def stage_contents_of(original_commit, subdirectory:)
  return if empty_commit_for_debug?

  original_commit.extract_contents_into(File.join(path, subdirectory))

  # First, track (almost) all files (including removed files) with .gitignore rules
  rugged_repo.index.add_all(subdirectory)

  # Then specify all the file paths explicily to track files
  # that matches .gitignore but is tracked in the original commit.
  # We cannot use Rugged::Index#add_all with :force option
  # since it has a bug where it raises strange error when adding files in a ignored directory.
  # https://github.com/libgit2/libgit2/issues/4377
  original_commit.files.each do |original_file_path|
    monorepo_file_path = File.join(subdirectory, original_file_path)
    rugged_repo.index.add(monorepo_file_path)
  end

  rugged_repo.index.write
end