Module: Bringit::Committing::Merge
- Included in:
- Bringit::Committing
- Defined in:
- lib/bringit/committing/merge.rb
Overview
Methods for merging a commit into another if the previous_head_sha is an ancestor of the current HEAD of a branch.
Instance Method Summary collapse
- #add_merge_data(options, index) ⇒ Object
- #conflict_hash(blob_object, stage) ⇒ Object
- #conflict_on_update(base_commit, user_commit, path) ⇒ Object
- #conflicts(options, base_commit, user_commit) ⇒ Object
- #create_merging_commit(parent_commit, index, tree_id, options) ⇒ Object
- #create_user_commit(options, previous_head_sha) ⇒ Object
- #diverged?(options, previous_head_sha) ⇒ Boolean
- #merge(options, previous_head_sha) ⇒ Object
- #merge_if_needed(options, previous_head_sha) ⇒ Object
- #raise_head_changed_error(conflicts, options) ⇒ Object
- #with_temp_user_reference(options, previous_head_sha) ⇒ Object
Instance Method Details
#add_merge_data(options, index) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/bringit/committing/merge.rb', line 38 def add_merge_data(, index) our_label = [: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: [:commit][:message]) else conflict[:merge_info] = nil end conflict end end |
#conflict_hash(blob_object, stage) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# 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) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 |
# 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) ⇒ Object
54 55 56 57 58 59 60 61 62 63 |
# File 'lib/bringit/committing/merge.rb', line 54 def conflicts(, base_commit, user_commit) [: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) ⇒ Object
112 113 114 115 |
# File 'lib/bringit/committing/merge.rb', line 112 def create_merging_commit(parent_commit, index, tree_id, ) parents = [parent_commit.oid] create_commit(index, tree_id, , parents) end |
#create_user_commit(options, previous_head_sha) ⇒ Object
92 93 94 95 96 97 98 99 100 101 |
# File 'lib/bringit/committing/merge.rb', line 92 def create_user_commit(, previous_head_sha) with_temp_user_reference(, previous_head_sha) do |reference| = .dup [:commit] = [:commit].dup [:commit][:branch] = reference.name [:commit][:update_ref] = false commit_sha = commit_multichange() rugged.lookup(commit_sha) end end |
#diverged?(options, previous_head_sha) ⇒ Boolean
15 16 17 18 |
# File 'lib/bringit/committing/merge.rb', line 15 def diverged?(, previous_head_sha) !previous_head_sha.nil? && branch_sha([:commit][:branch]) != previous_head_sha end |
#merge(options, previous_head_sha) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/bringit/committing/merge.rb', line 20 def merge(, previous_head_sha) user_commit = create_user_commit(, previous_head_sha) base_commit = commit([:commit][:branch]).raw_commit index = rugged.merge_commits(base_commit, user_commit) if index.conflicts? enriched_conflicts = add_merge_data(, index) raise_head_changed_error(enriched_conflicts, ) end tree_id = index.write_tree(rugged) found_conflicts = conflicts(, base_commit, user_commit) if found_conflicts.any? raise_head_changed_error(found_conflicts, ) end create_merging_commit(base_commit, index, tree_id, ) end |
#merge_if_needed(options, previous_head_sha) ⇒ Object
8 9 10 11 12 13 |
# File 'lib/bringit/committing/merge.rb', line 8 def merge_if_needed(, previous_head_sha) return [:noop, nil] unless diverged?(, previous_head_sha) commit_sha = merge(, previous_head_sha) return [:merge_commit_created, commit_sha] end |
#raise_head_changed_error(conflicts, options) ⇒ Object
117 118 119 120 121 122 |
# File 'lib/bringit/committing/merge.rb', line 117 def raise_head_changed_error(conflicts, ) = <<MESSAGE The branch has changed since editing and cannot be merged automatically. MESSAGE raise HeadChangedError.new(, conflicts, ) end |
#with_temp_user_reference(options, previous_head_sha) ⇒ Object
103 104 105 106 107 108 109 110 |
# File 'lib/bringit/committing/merge.rb', line 103 def with_temp_user_reference(, 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 |