Class: Rails::Credentials::Conflict::GitConflictHandler
- Inherits:
-
Object
- Object
- Rails::Credentials::Conflict::GitConflictHandler
- Defined in:
- lib/rails/credentials/conflict/git_conflict_handler.rb,
sig/rails/credentials/conflict/git_conflict_handler.rbs
Overview
Interacts with git to read conflict stages, detect merge state, and stage resolved files.
Uses git's staging area to access the three versions of a conflicted file (base, ours, theirs) and determines labels for the merge participants.
Constant Summary collapse
- STAGE_BASE =
1- STAGE_OURS =
2- STAGE_THEIRS =
3
Instance Method Summary collapse
- #build_label(branch_name, commit_sha) ⇒ String
- #detect_head_ref ⇒ String
- #get_current_branch ⇒ String
- #get_incoming_branch(head_ref) ⇒ String
- #get_merge_base_sha(head_ref) ⇒ String
-
#get_merge_labels ⇒ merge_labels
Returns a Hash of labels for the three merge participants (+:ours+,
:base,:theirs), each containing a branch name and short SHA. - #get_short_sha(ref) ⇒ String
-
#get_version(version) ⇒ String
Retrieves the encrypted content for the given
version(:base, :ours, or :theirs) from the git staging area. -
#initialize(credentials_path, relative_path) ⇒ GitConflictHandler
constructor
A new instance of GitConflictHandler.
- #stage_for_version(version) ⇒ Integer
-
#stage_resolved_file! ⇒ void
Stages the resolved credentials file with
git add. -
#validate_conflict! ⇒ void
Verifies that the credentials file exists and is in a conflicted state (UU or AA in
git status --porcelain).
Constructor Details
#initialize(credentials_path, relative_path) ⇒ GitConflictHandler
Returns a new instance of GitConflictHandler.
19 20 21 22 |
# File 'lib/rails/credentials/conflict/git_conflict_handler.rb', line 19 def initialize(credentials_path, relative_path) @credentials_path = credentials_path.to_s @relative_path = relative_path.to_s end |
Instance Method Details
#build_label(branch_name, commit_sha) ⇒ String
92 93 94 |
# File 'lib/rails/credentials/conflict/git_conflict_handler.rb', line 92 def build_label(branch_name, commit_sha) "#{branch_name} (#{commit_sha})" end |
#detect_head_ref ⇒ String
83 84 85 86 87 88 89 90 |
# File 'lib/rails/credentials/conflict/git_conflict_handler.rb', line 83 def detect_head_ref %w[MERGE_HEAD CHERRY_PICK_HEAD REBASE_HEAD].each do |ref| _, status = Open3.capture2("git", "rev-parse", "--verify", ref) return ref if status.success? end "MERGE_HEAD" end |
#get_current_branch ⇒ String
96 97 98 99 100 |
# File 'lib/rails/credentials/conflict/git_conflict_handler.rb', line 96 def get_current_branch branch, status = Open3.capture2("git", "rev-parse", "--abbrev-ref", "HEAD") branch = branch.strip status.success? && !branch.empty? ? branch : "HEAD" end |
#get_incoming_branch(head_ref) ⇒ String
102 103 104 105 106 |
# File 'lib/rails/credentials/conflict/git_conflict_handler.rb', line 102 def get_incoming_branch(head_ref) branch, status = Open3.capture2("git", "name-rev", "--name-only", head_ref) branch = branch.strip status.success? && !branch.empty? ? branch : head_ref end |
#get_merge_base_sha(head_ref) ⇒ String
113 114 115 116 117 118 119 120 121 |
# File 'lib/rails/credentials/conflict/git_conflict_handler.rb', line 113 def get_merge_base_sha(head_ref) ours_sha, s1 = Open3.capture2("git", "rev-parse", "HEAD") theirs_sha, s2 = Open3.capture2("git", "rev-parse", head_ref) return "unknown" unless s1.success? && s2.success? base_sha, s3 = Open3.capture2("git", "merge-base", ours_sha.strip, theirs_sha.strip) s3.success? ? base_sha.strip[0..7] : "unknown" end |
#get_merge_labels ⇒ merge_labels
Returns a Hash of labels for the three merge participants
(+:ours+, :base, :theirs), each containing a branch name
and short SHA.
62 63 64 65 66 67 68 69 70 |
# File 'lib/rails/credentials/conflict/git_conflict_handler.rb', line 62 def get_merge_labels head_ref = detect_head_ref { ours: build_label(get_current_branch, get_short_sha("HEAD")), base: build_label("ancestor", get_merge_base_sha(head_ref)), theirs: build_label(get_incoming_branch(head_ref), get_short_sha(head_ref)) } end |
#get_short_sha(ref) ⇒ String
108 109 110 111 |
# File 'lib/rails/credentials/conflict/git_conflict_handler.rb', line 108 def get_short_sha(ref) sha, status = Open3.capture2("git", "rev-parse", "--short=8", ref) status.success? ? sha.strip : "unknown" end |
#get_version(version) ⇒ String
Retrieves the encrypted content for the given version (:base, :ours, or :theirs)
from the git staging area. Returns an empty string on failure.
40 41 42 43 44 45 46 47 |
# File 'lib/rails/credentials/conflict/git_conflict_handler.rb', line 40 def get_version(version) stage_number = stage_for_version(version) content, status = Open3.capture2( "git", "show", ":#{stage_number}:#{@relative_path}", binmode: true ) status.success? ? content.strip : "" end |
#stage_for_version(version) ⇒ Integer
74 75 76 77 78 79 80 81 |
# File 'lib/rails/credentials/conflict/git_conflict_handler.rb', line 74 def stage_for_version(version) case version when :base then STAGE_BASE when :ours then STAGE_OURS when :theirs then STAGE_THEIRS else raise Error, "Unknown version: #{version}" end end |
#stage_resolved_file! ⇒ void
This method returns an undefined value.
Stages the resolved credentials file with git add.
Raises Error if the command fails.
51 52 53 54 55 56 57 |
# File 'lib/rails/credentials/conflict/git_conflict_handler.rb', line 51 def stage_resolved_file! _, status = Open3.capture2("git", "add", @credentials_path) return if status.success? raise Error, "Failed to stage resolved file: #{@credentials_path}" end |
#validate_conflict! ⇒ void
This method returns an undefined value.
Verifies that the credentials file exists and is in a conflicted
state (UU or AA in git status --porcelain).
Raises Error otherwise.
27 28 29 30 31 32 33 34 35 36 |
# File 'lib/rails/credentials/conflict/git_conflict_handler.rb', line 27 def validate_conflict! raise Error, "Credentials file not found: #{@credentials_path}" unless File.exist?(@credentials_path) git_status, status = Open3.capture2("git", "status", "--porcelain", @credentials_path) git_status = git_status.strip return if status.success? && (git_status.start_with?("UU") || git_status.start_with?("AA")) raise Error, "No git conflict detected for #{@credentials_path}" end |