class ModuleSync::Repository
Wrapper for Git
in ModuleSync
context
Public Class Methods
new(directory:, remote:)
click to toggle source
# File lib/modulesync/repository.rb, line 6 def initialize(directory:, remote:) @directory = directory @remote = remote end
Public Instance Methods
checkout_branch(branch)
click to toggle source
# File lib/modulesync/repository.rb, line 92 def checkout_branch(branch) selected_branch = branch || repo.current_branch || 'master' repo.branch(selected_branch).checkout selected_branch end
default_branch()
click to toggle source
# File lib/modulesync/repository.rb, line 33 def default_branch symbolic_ref = repo.branches.find { |b| b.full =~ %r{remotes/origin/HEAD} } return unless symbolic_ref %r{remotes/origin/HEAD\s+->\s+origin/(?<branch>.+?)$}.match(symbolic_ref.full)[:branch] end
git()
click to toggle source
# File lib/modulesync/repository.rb, line 11 def git @git ||= Git.open @directory end
local_branch_exists?(branch)
click to toggle source
# File lib/modulesync/repository.rb, line 24 def local_branch_exists?(branch) repo.branches.local.collect(&:name).include?(branch) end
prepare_workspace(branch)
click to toggle source
# File lib/modulesync/repository.rb, line 65 def prepare_workspace(branch) # Repo needs to be cloned in the cwd if !Dir.exist?("#{@directory}/.git") puts "Cloning repository fresh from '#{@remote}'" @git = Git.clone(@remote, @directory) switch_branch(branch) # Repo already cloned, check out master and override local changes else # Some versions of git can't properly handle managing a repo from outside the repo directory Dir.chdir(@directory) do puts "Overriding any local changes to repository in '#{@directory}'" @git = Git.open('.') repo.fetch repo.reset_hard switch_branch(branch) git.pull('origin', branch) if remote_branch_exists?(branch) end end end
remote_branch_differ?(local_branch, remote_branch)
click to toggle source
# File lib/modulesync/repository.rb, line 28 def remote_branch_differ?(local_branch, remote_branch) !remote_branch_exists?(remote_branch) || repo.diff("#{local_branch}..origin/#{remote_branch}").any? end
remote_branch_exists?(branch)
click to toggle source
# File lib/modulesync/repository.rb, line 20 def remote_branch_exists?(branch) repo.branches.remote.collect(&:name).include?(branch) end
repo()
click to toggle source
This is an alias to minimize code alteration
# File lib/modulesync/repository.rb, line 16 def repo git end
show_changes(options)
click to toggle source
# File lib/modulesync/repository.rb, line 145 def show_changes(options) checkout_branch(options[:branch]) puts 'Files changed:' repo.diff('HEAD', '--').each do |diff| puts diff.patch end puts 'Files added:' untracked_unignored_files.each_key do |file| puts file end puts "\n\n" puts '--------------------------------' end
submit_changes(files, options)
click to toggle source
Git
add/rm, git commit, git push
# File lib/modulesync/repository.rb, line 99 def submit_changes(files, options) message = options[:message] branch = checkout_branch(options[:branch]) files.each do |file| if repo.status.deleted.include?(file) repo.remove(file) elsif File.exist?("#{@directory}/#{file}") repo.add(file) end end begin opts_commit = {} opts_push = {} opts_commit = { :amend => true } if options[:amend] opts_push = { :force => true } if options[:force] if options[:pre_commit_script] script = "#{File.dirname(File.dirname(__FILE__))}/../contrib/#{options[:pre_commit_script]}" `#{script} #{@directory}` end repo.commit(message, opts_commit) if options[:remote_branch] if remote_branch_differ?(branch, options[:remote_branch]) repo.push('origin', "#{branch}:#{options[:remote_branch]}", opts_push) end else repo.push('origin', branch, opts_push) end rescue Git::GitExecuteError => e raise unless e.message.match?(/working (directory|tree) clean/) puts "There were no changes in '#{@directory}'. Not committing." return false end true end
switch_branch(branch)
click to toggle source
# File lib/modulesync/repository.rb, line 39 def switch_branch(branch) unless branch branch = default_branch puts "Using repository's default branch: #{branch}" end return if repo.current_branch == branch if local_branch_exists?(branch) puts "Switching to branch #{branch}" repo.checkout(branch) elsif remote_branch_exists?(branch) puts "Creating local branch #{branch} from origin/#{branch}" repo.checkout("origin/#{branch}") repo.branch(branch).checkout else base_branch = default_branch unless base_branch puts "Couldn't detect default branch. Falling back to assuming 'master'" base_branch = 'master' end puts "Creating new branch #{branch} from #{base_branch}" repo.checkout("origin/#{base_branch}") repo.branch(branch).checkout end end
tag(version, tag_pattern)
click to toggle source
# File lib/modulesync/repository.rb, line 85 def tag(version, tag_pattern) tag = tag_pattern % version puts "Tagging with #{tag}" repo.add_tag(tag) repo.push('origin', tag) end
untracked_unignored_files()
click to toggle source
Needed because of a bug in the git gem that lists ignored files as untracked under some circumstances github.com/schacon/ruby-git/issues/130
# File lib/modulesync/repository.rb, line 139 def untracked_unignored_files ignore_path = "#{@directory}/.gitignore" ignored = File.exist?(ignore_path) ? File.read(ignore_path).split : [] repo.status.untracked.keep_if { |f, _| ignored.none? { |i| File.fnmatch(i, f) } } end