class DTK::Client::CommandHelper::GitRepo::Merge

Public Class Methods

merge(repo, remote_branch_ref, opts = {}) click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 35
def self.merge(repo, remote_branch_ref, opts = {})
  new(repo, remote_branch_ref, opts).merge
end
new(repo, remote_branch_ref, opts = {}) click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 22
def initialize(repo, remote_branch_ref, opts = {})
  @repo              = repo
  @remote_branch_ref = remote_branch_ref
  @local_branch      = repo.local_branch_name
  
  # options
  @opts_commit_sha = opts[:commit_sha]
  @opts_force = opts[:force]
  @opts_ignore_dependency_merge_conflict = opts[:ignore_dependency_merge_conflict]
  @opts_full_module_name = opts[:full_module_name]
  @opts_command = opts[:command]
end

Public Instance Methods

merge() click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 39
def merge
  if @opts_force
    merge_force()
  else
    # check if merge needed
    merge_rel = merge_relationship()
    case merge_rel
     when :equal 
      response__no_diffs()
     when :local_ahead, :branchpoint
      merge_not_fast_forward(merge_rel)
     when :local_behind
      merge_simple()
     else
      raise Error.new("Unexpected merge_rel (#{merge_rel})")
    end
  end
end

Private Instance Methods

any_conflicts?() click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 111
def any_conflicts?
  # TODO: optimization is to combine this with mereg to have merge_if_no_conflics?
  #       and if no conflicts just commit and merge --no-commit
  ret = nil
  begin
    @repo.command('merge',['--no-commit', @remote_branch_ref])
   rescue ::Git::GitExecuteError
    ret = true
  ensure
    safe_execute do
      @repo.command('merge',['--abort'])
    end
  end
  ret
end
compute_diffs() click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 139
def compute_diffs
  GitRepo.compute_diffs(@repo,  @remote_branch_ref)
end
diffs__no_diffs() click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 135
def diffs__no_diffs
  GitRepo.diffs__no_diffs
end
merge_force() click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 60
def merge_force
  diffs = compute_diffs()
  # TODO: should put in a commit message that merged from remote repo
  @repo.merge_theirs(@remote_branch_ref)
  response(diffs)
end
merge_not_fast_forward(merge_rel) click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 67
def merge_not_fast_forward(merge_rel)
  if any_conflicts?
    # @opts_ignore_dependency_merge_conflict means called indirectly
    if @opts_ignore_dependency_merge_conflict
      # TODO: hard-wired that dependency is a component module in message: 'component-module/..
      custom_message = "Unable to do fast-forward merge. You can go to 'component-module/#{@opts_full_module_name}' and pull with --force option but all local changes will be lost." 
      response(compute_diffs, :custom_message => custom_message)
    else
      err_msg = 'Unable to do fast-forward merge. You can use --force'
      err_msg << " on #{@opts_command}" if @opts_command
      err_msg <<  ', but all local changes will be lost on target that is being pushed to.'
      raise ErrorUsage.new(err_msg)
    end
  elsif  merge_rel == :local_ahead
    response__no_diffs(:custom_message => 'No op because local module is ahead')
  else
    merge_simple()
  end
end
merge_relationship() click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 107
def merge_relationship
  @repo.merge_relationship(:remote_branch, @remote_branch_ref)    
end
merge_simple() click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 87
def merge_simple
  # see if any diffs between fetched remote and local branch
  # this has be done after commit
  diffs = compute_diffs()
  return diffs unless diffs.any_diffs?()
  
  safe_execute do
    # TODO: should put in a commit message that merged from remote repo
    @repo.merge(@remote_branch_ref)
  end
  
  if commit_sha = @opts_commit_sha
    if commit_sha != @repo.head_commit_sha()
      raise Error.new("Git synchronization problem: expected local head to have sha (#{commit_sha})")
    end
  end
  
  response(diffs)
end
response(diffs, opts_response = {}) click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 131
def response(diffs, opts_response = {})
  { :diffs => diffs, :commit_sha => @repo.head_commit_sha() }.merge(opts_response)
end
response__no_diffs(opts_response = {}) click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 127
def response__no_diffs(opts_response = {})
  response(diffs__no_diffs(), opts_response)
end
safe_execute() { || ... } click to toggle source
# File lib/command_helpers/git_repo/merge.rb, line 143
def safe_execute(&block)
  begin
    yield
   rescue Exception
    nil
  end
end