class FlashFlow::Git
Constants
- ATTRIBUTES
- UNMERGED_STATUSES
Attributes
working_branch[R]
Public Class Methods
new(config, logger=nil)
click to toggle source
# File lib/flash_flow/git.rb, line 13 def initialize(config, logger=nil) @cmd_runner = CmdRunner.new(logger: logger) config['release_branch'] ||= config['master_branch'] config['remote'] ||= config['merge_remote'] # For backwards compatibility ATTRIBUTES.each do |attr| unless config.has_key?(attr.to_s) raise RuntimeError.new("git configuration missing. Required config parameters: #{ATTRIBUTES}") end instance_variable_set("@#{attr}", config[attr.to_s]) end @working_branch = current_branch end
Public Instance Methods
add_and_commit(files, message, opts={})
click to toggle source
# File lib/flash_flow/git.rb, line 56 def add_and_commit(files, message, opts={}) files = [files].flatten run("add #{'-f ' if opts[:add] && opts[:add][:force]}#{files.join(' ')}") run("commit -m '#{message}'") end
ahead_of_master?(branch)
click to toggle source
# File lib/flash_flow/git.rb, line 246 def ahead_of_master?(branch) branch_exists?(branch) && !master_branch_contains?(get_sha(branch)) end
branch_contains?(branch, ref)
click to toggle source
# File lib/flash_flow/git.rb, line 66 def branch_contains?(branch, ref) run("branch -a --contains #{ref}", log: CmdRunner::LOG_CMD) last_stdout.split("\n").detect { |str| str[2..-1] == branch } end
branch_exists?(branch)
click to toggle source
# File lib/flash_flow/git.rb, line 241 def branch_exists?(branch) run("rev-parse --verify #{branch}") last_success? end
commit_rerere(current_rereres)
click to toggle source
# File lib/flash_flow/git.rb, line 92 def commit_rerere(current_rereres) return unless use_rerere @cmd_runner.run('mkdir rr-cache') @cmd_runner.run('rm -rf rr-cache/*') current_rereres.each do |rerere| @cmd_runner.run("cp -R .git/rr-cache/#{rerere} rr-cache/") end run('add rr-cache/') run("commit -m 'Update rr-cache'") end
conflicted_files()
click to toggle source
# File lib/flash_flow/git.rb, line 156 def conflicted_files run("diff --name-only --diff-filter=U") last_stdout.split("\n") end
copy_temp_to_branch(branch, squash_message = nil)
click to toggle source
# File lib/flash_flow/git.rb, line 184 def copy_temp_to_branch(branch, squash_message = nil) reset_local_merge_branch run("checkout #{temp_merge_branch}") run("merge --strategy=ours --no-edit #{branch}") run("checkout #{branch}") run("merge #{temp_merge_branch}") squash_commits(branch, squash_message) if squash_message end
current_branch()
click to toggle source
# File lib/flash_flow/git.rb, line 161 def current_branch run("rev-parse --abbrev-ref HEAD") last_stdout.strip end
delete_temp_merge_branch()
click to toggle source
# File lib/flash_flow/git.rb, line 203 def delete_temp_merge_branch in_branch(master_branch) do run("branch -d #{temp_merge_branch}") end end
get_sha(branch, opts={})
click to toggle source
# File lib/flash_flow/git.rb, line 232 def get_sha(branch, opts={}) if opts[:short] run("rev-parse --short #{branch}") else run("rev-parse #{branch}") end last_stdout.strip if last_success? end
in_branch(branch) { || ... }
click to toggle source
# File lib/flash_flow/git.rb, line 217 def in_branch(branch) begin starting_branch = current_branch run("checkout #{branch}") yield ensure run("checkout #{starting_branch}") end end
in_dir() { || ... }
click to toggle source
# File lib/flash_flow/git.rb, line 30 def in_dir Dir.chdir(@cmd_runner.dir) do yield end end
in_merge_branch(&block)
click to toggle source
# File lib/flash_flow/git.rb, line 213 def in_merge_branch(&block) in_branch(merge_branch, &block) end
in_original_merge_branch() { || ... }
click to toggle source
# File lib/flash_flow/git.rb, line 75 def in_original_merge_branch in_branch("#{remote}/#{merge_branch}") { yield } end
in_temp_merge_branch(&block)
click to toggle source
# File lib/flash_flow/git.rb, line 209 def in_temp_merge_branch(&block) in_branch(temp_merge_branch, &block) end
initialize_rerere(copy_from_dir=nil)
click to toggle source
# File lib/flash_flow/git.rb, line 84 def initialize_rerere(copy_from_dir=nil) return unless use_rerere @cmd_runner.run('mkdir .git/rr-cache') @cmd_runner.run('cp -R rr-cache/* .git/rr-cache/') @cmd_runner.run("cp -R #{File.join(copy_from_dir, '.git/rr-cache/*')} .git/rr-cache/") if copy_from_dir end
last_command()
click to toggle source
# File lib/flash_flow/git.rb, line 40 def last_command @cmd_runner.last_command end
last_stdout()
click to toggle source
# File lib/flash_flow/git.rb, line 36 def last_stdout @cmd_runner.last_stdout end
last_success?()
click to toggle source
# File lib/flash_flow/git.rb, line 44 def last_success? @cmd_runner.last_success? end
master_branch_contains?(sha)
click to toggle source
# File lib/flash_flow/git.rb, line 71 def master_branch_contains?(sha) branch_contains?("remotes/#{remote}/#{master_branch}", sha) end
merge(branch)
click to toggle source
# File lib/flash_flow/git.rb, line 62 def merge(branch) run("merge #{branch}") end
most_recent_commit()
click to toggle source
# File lib/flash_flow/git.rb, line 166 def most_recent_commit run("show -s --format=%cd head") end
push(branch, force=false)
click to toggle source
# File lib/flash_flow/git.rb, line 180 def push(branch, force=false) run("push #{'-f' if force} #{remote} #{branch}:#{branch}") end
read_file_from_merge_branch(filename)
click to toggle source
# File lib/flash_flow/git.rb, line 79 def read_file_from_merge_branch(filename) run("show #{remote}/#{merge_branch}:#{filename}", log: CmdRunner::LOG_CMD) last_stdout end
rerere_resolve!()
click to toggle source
# File lib/flash_flow/git.rb, line 104 def rerere_resolve! return false unless use_rerere if unresolved_conflicts.empty? merging_files = staged_and_working_dir_files.select { |s| UNMERGED_STATUSES.include?(s[0..1]) }.map { |s| s[3..-1] } conflicts = conflicted_files run("add #{merging_files.join(" ")}") run('commit --no-edit') resolutions(conflicts) else false end end
reset_local_merge_branch()
click to toggle source
# File lib/flash_flow/git.rb, line 194 def reset_local_merge_branch in_branch(master_branch) do run("branch -D #{merge_branch}") run("checkout -b #{merge_branch}") run("reset --hard #{remote}/#{merge_branch}") run("clean -x -f -d") end end
reset_temp_merge_branch()
click to toggle source
# File lib/flash_flow/git.rb, line 170 def reset_temp_merge_branch in_branch(master_branch) do run("fetch #{remote}") run("branch -D #{temp_merge_branch}") run("checkout -b #{temp_merge_branch}") run("reset --hard #{remote}/#{master_branch}") run("clean -x -f -d") end end
resolution_candidates(file)
click to toggle source
git rerere doesn't give you a deterministic way to determine which resolution was used
# File lib/flash_flow/git.rb, line 137 def resolution_candidates(file) @cmd_runner.run("diff -q --from-file #{file} .git/rr-cache/*/postimage*", log: CmdRunner::LOG_CMD) different_files = split_diff_lines(@cmd_runner.last_stdout) @cmd_runner.run('ls -la .git/rr-cache/*/postimage*', log: CmdRunner::LOG_CMD) all_files = split_diff_lines(@cmd_runner.last_stdout) all_files - different_files end
resolutions(files)
click to toggle source
# File lib/flash_flow/git.rb, line 128 def resolutions(files) {}.tap do |hash| files.map do |file| hash[file] = resolution_candidates(file) end.flatten end end
run(cmd, opts={})
click to toggle source
# File lib/flash_flow/git.rb, line 48 def run(cmd, opts={}) @cmd_runner.run("git #{cmd}", opts) end
split_diff_lines(arr)
click to toggle source
# File lib/flash_flow/git.rb, line 147 def split_diff_lines(arr) arr.split("\n").map { |s| s.split(".git/rr-cache/").last.split("/postimage").first } end
staged_and_working_dir_files()
click to toggle source
# File lib/flash_flow/git.rb, line 151 def staged_and_working_dir_files run("status --porcelain") last_stdout.split("\n").reject { |line| line[0..1] == '??' } end
temp_merge_branch()
click to toggle source
# File lib/flash_flow/git.rb, line 228 def temp_merge_branch "flash_flow-#{merge_branch}" end
unresolved_conflicts()
click to toggle source
# File lib/flash_flow/git.rb, line 120 def unresolved_conflicts in_dir do conflicted_files.map do |file| File.open(file) { |f| f.grep(/>>>>/) }.empty? ? nil : file end.compact end end
version()
click to toggle source
# File lib/flash_flow/git.rb, line 250 def version run('--version') semver_regex = Regexp.new('.*(\d+\.\d+\.\d+).*') running_version = last_stdout.strip if semver = semver_regex.match(running_version) semver[1] end end
working_dir()
click to toggle source
# File lib/flash_flow/git.rb, line 52 def working_dir @cmd_runner.dir end
Private Instance Methods
squash_commits(branch, commit_message)
click to toggle source
# File lib/flash_flow/git.rb, line 261 def squash_commits(branch, commit_message) unless branch_exists?("#{remote}/#{branch}") run("push #{remote} #{master_branch}:#{branch}") end # Get all the files that differ between existing acceptance and new acceptance run("diff --name-only #{remote}/#{branch} #{branch}") files = last_stdout.split("\n") run("reset #{remote}/#{branch}") run("add -f #{files.map { |f| "\"#{Shellwords.escape(f)}\"" }.join(" ")}") run("commit -m '#{commit_message}'") end