module Bringit::Committing::Merge
Methods for merging a commit into another if the previous_head_sha is an ancestor of the current HEAD of a branch.
Public Instance Methods
add_merge_data(options, index)
click to toggle source
# File lib/bringit/committing/merge.rb, line 38 def add_merge_data(options, index) our_label = options[:commit][:branch].sub(%r{\Arefs/heads/}, '') index.conflicts.map do |conflict| if conflict[:ancestor] && conflict[:ours] && conflict[:theirs] conflict[:merge_info] = index.merge_file(conflict[:ours][:path], ancestor_label: 'parent', our_label: our_label, their_label: options[:commit][:message]) else conflict[:merge_info] = nil end conflict end end
conflict_hash(blob_object, stage)
click to toggle source
# File lib/bringit/committing/merge.rb, line 77 def conflict_hash(blob_object, stage) {path: blob_object.path, oid: blob_object.id, dev: 0, ino: 0, mode: blob_object.mode.to_i(8), gid: 0, uid: 0, file_size: 0, valid: false, stage: stage, ctime: Time.at(0), mtime: Time.at(0)} end
conflict_on_update(base_commit, user_commit, path)
click to toggle source
# File lib/bringit/committing/merge.rb, line 65 def conflict_on_update(base_commit, user_commit, path) base_blob = blob(base_commit.oid, path) return nil unless base_blob.nil? ancestor_blob = blob(base_commit.parents.first.oid, path) user_blob = blob(user_commit.oid, path) result = {merge_info: nil, ours: nil} result[:ancestor] = conflict_hash(ancestor_blob, 1) if ancestor_blob result[:theirs] = conflict_hash(user_blob, 3) if user_blob result end
conflicts(options, base_commit, user_commit)
click to toggle source
# File lib/bringit/committing/merge.rb, line 54 def conflicts(options, base_commit, user_commit) options[:files].map do |file| case file[:action] when :update conflict_on_update(base_commit, user_commit, file[:path]) when :rename_and_update conflict_on_update(base_commit, user_commit, file[:previous_path]) end end.compact end
create_merging_commit(parent_commit, index, tree_id, options)
click to toggle source
# File lib/bringit/committing/merge.rb, line 112 def create_merging_commit(parent_commit, index, tree_id, options) parents = [parent_commit.oid] create_commit(index, tree_id, options, parents) end
create_user_commit(options, previous_head_sha)
click to toggle source
# File lib/bringit/committing/merge.rb, line 92 def create_user_commit(options, previous_head_sha) with_temp_user_reference(options, previous_head_sha) do |reference| new_options = options.dup new_options[:commit] = options[:commit].dup new_options[:commit][:branch] = reference.name new_options[:commit][:update_ref] = false commit_sha = commit_multichange(new_options) rugged.lookup(commit_sha) end end
diverged?(options, previous_head_sha)
click to toggle source
# File lib/bringit/committing/merge.rb, line 15 def diverged?(options, previous_head_sha) !previous_head_sha.nil? && branch_sha(options[:commit][:branch]) != previous_head_sha end
merge(options, previous_head_sha)
click to toggle source
# File lib/bringit/committing/merge.rb, line 20 def merge(options, previous_head_sha) user_commit = create_user_commit(options, previous_head_sha) base_commit = commit(options[:commit][:branch]).raw_commit index = rugged.merge_commits(base_commit, user_commit) if index.conflicts? enriched_conflicts = add_merge_data(options, index) raise_head_changed_error(enriched_conflicts, options) end tree_id = index.write_tree(rugged) found_conflicts = conflicts(options, base_commit, user_commit) if found_conflicts.any? raise_head_changed_error(found_conflicts, options) end create_merging_commit(base_commit, index, tree_id, options) end
merge_if_needed(options, previous_head_sha)
click to toggle source
# File lib/bringit/committing/merge.rb, line 8 def merge_if_needed(options, previous_head_sha) return [:noop, nil] unless diverged?(options, previous_head_sha) commit_sha = merge(options, previous_head_sha) return [:merge_commit_created, commit_sha] end
raise_head_changed_error(conflicts, options)
click to toggle source
# File lib/bringit/committing/merge.rb, line 117 def raise_head_changed_error(conflicts, options) message = <<MESSAGE The branch has changed since editing and cannot be merged automatically. MESSAGE raise HeadChangedError.new(message, conflicts, options) end
with_temp_user_reference(options, previous_head_sha) { |reference| ... }
click to toggle source
# File lib/bringit/committing/merge.rb, line 103 def with_temp_user_reference(options, previous_head_sha) refname = "#{Time.now.to_f.to_s.tr('.', '')}_#{SecureRandom.hex(20)}" full_refname = "refs/merges/user/#{refname}" reference = rugged.references.create(full_refname, previous_head_sha) yield(reference) ensure rugged.references.delete(reference) end