module GitReflow::GitHelpers

Includes many helper methods for common tasks within a git repository.

Public Instance Methods

append_to_merge_commit_message(message = '', merge_method: "squash") click to toggle source
# File lib/git_reflow/git_helpers.rb, line 117
def append_to_merge_commit_message(message = '', merge_method: "squash")
  tmp_merge_message_path  = "#{git_root_dir}/.git/tmp_merge_msg"
  dest_merge_message_path = merge_message_path(merge_method: merge_method)

  run "touch #{tmp_merge_message_path}"

  File.open(tmp_merge_message_path, "w") do |file_content|
    file_content.puts message
    if File.exists? dest_merge_message_path
      File.foreach(dest_merge_message_path) do |line|
        file_content.puts line
      end
    end
  end

  run "mv #{tmp_merge_message_path} #{dest_merge_message_path}"
end
current_branch() click to toggle source
# File lib/git_reflow/git_helpers.rb, line 47
def current_branch
  run("git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g'", loud: false).strip
end
default_base_branch() click to toggle source
# File lib/git_reflow/git_helpers.rb, line 41
def default_base_branch
  base_branch_name = GitReflow::Config.get('reflow.base-branch')
  return 'master' if base_branch_name.empty?
  base_branch_name
end
default_editor() click to toggle source
# File lib/git_reflow/git_helpers.rb, line 11
def default_editor
  ENV['EDITOR'] || 'vi'
end
fetch_destination(destination_branch) click to toggle source
# File lib/git_reflow/git_helpers.rb, line 94
def fetch_destination(destination_branch)
  run_command_with_label "git fetch origin #{destination_branch}"
end
get_first_commit_message() click to toggle source
# File lib/git_reflow/git_helpers.rb, line 79
def get_first_commit_message
  run('git log --pretty=format:"%s" --no-merges -n 1', loud: false).strip
end
git_editor_command() click to toggle source
# File lib/git_reflow/git_helpers.rb, line 22
def git_editor_command
  git_editor = GitReflow::Config.get('core.editor')
  if !git_editor.empty?
    git_editor
  else
    default_editor
  end
end
git_root_dir() click to toggle source
# File lib/git_reflow/git_helpers.rb, line 15
def git_root_dir
  return @git_root_dir unless @git_root_dir.to_s.empty?
  return @git_root_dir = Dir.pwd if Dir.exists?("#{Dir.pwd}/.git")

  @git_root_dir = run('git rev-parse --show-toplevel', loud: false).strip
end
merge_commit_template() click to toggle source
# File lib/git_reflow/git_helpers.rb, line 66
def merge_commit_template
  custom_template = GitReflow::Config.get('templates.merge-commit')
  filenames_to_try = %w[.github/MERGE_COMMIT_TEMPLATE.md
                        .github/MERGE_COMMIT_TEMPLATE
                        MERGE_COMMIT_TEMPLATE.md
                        MERGE_COMMIT_TEMPLATE].map do |file|
    "#{git_root_dir}/#{file}"
  end
  filenames_to_try.unshift(custom_template) unless custom_template.empty?

  parse_first_matching_template_file(filenames_to_try)
end
merge_message_path(merge_method: nil) click to toggle source
# File lib/git_reflow/git_helpers.rb, line 135
def merge_message_path(merge_method: nil)
  merge_method = merge_method || GitReflow::Config.get("reflow.merge-method")
  merge_method = "squash" if "#{merge_method}".length < 1
  if merge_method =~ /squash/i
    "#{git_root_dir}/.git/SQUASH_MSG"
  else
    "#{git_root_dir}/.git/MERGE_MSG"
  end
end
pull_request_template() click to toggle source
# File lib/git_reflow/git_helpers.rb, line 51
def pull_request_template
  custom_template = GitReflow::Config.get('templates.pull-request')
  filenames_to_try = %w[
    .github/PULL_REQUEST_TEMPLATE.md
    .github/PULL_REQUEST_TEMPLATE
    PULL_REQUEST_TEMPLATE.md
    PULL_REQUEST_TEMPLATE
  ].map do |file|
    "#{git_root_dir}/#{file}"
  end
  filenames_to_try.unshift(custom_template) unless custom_template.empty?

  parse_first_matching_template_file(filenames_to_try)
end
push_current_branch(options = {}) click to toggle source
# File lib/git_reflow/git_helpers.rb, line 83
def push_current_branch(options = {})
  remote = options[:remote] || 'origin'
  run_command_with_label "git push #{remote} #{current_branch}"
end
remote_repo_name() click to toggle source
# File lib/git_reflow/git_helpers.rb, line 36
def remote_repo_name
  return '' if GitReflow::Config.get('remote.origin.url').empty?
  extract_remote_user_and_repo_from_remote_url(GitReflow::Config.get('remote.origin.url'))[:repo]
end
remote_user() click to toggle source
# File lib/git_reflow/git_helpers.rb, line 31
def remote_user
  return '' if GitReflow::Config.get('remote.origin.url').empty?
  extract_remote_user_and_repo_from_remote_url(GitReflow::Config.get('remote.origin.url'))[:user]
end
update_current_branch(options = {}) click to toggle source
# File lib/git_reflow/git_helpers.rb, line 88
def update_current_branch(options = {})
  remote = options[:remote] || 'origin'
  run_command_with_label "git pull #{remote} #{current_branch}"
  push_current_branch(options)
end
update_destination(destination_branch, options = {}) click to toggle source
# File lib/git_reflow/git_helpers.rb, line 98
def update_destination(destination_branch, options = {})
  origin_branch = current_branch
  remote = options[:remote] || 'origin'
  run_command_with_label "git checkout #{destination_branch}"
  run_command_with_label "git pull #{remote} #{destination_branch}"
  run_command_with_label "git checkout #{origin_branch}"
end
update_feature_branch(options = {}) click to toggle source
# File lib/git_reflow/git_helpers.rb, line 106
def update_feature_branch(options = {})
  base_branch = options[:base]
  remote = options[:remote]
  update_destination(base_branch, options) 

  # update feature branch in case there are multiple authors and remote changes
  run_command_with_label "git pull origin #{current_branch}"
  # rebase on base branch
  run_command_with_label "git merge #{base_branch}"
end

Private Instance Methods

extract_remote_user_and_repo_from_remote_url(remote_url) click to toggle source
# File lib/git_reflow/git_helpers.rb, line 161
def extract_remote_user_and_repo_from_remote_url(remote_url)
  result = { user: '', repo: '' }
  return result unless "#{remote_url}".length > 0

  if remote_url =~ /\Agit@/i
    result[:user] = remote_url[/[\/:](\w|-|\.)+/i][1..-1]
    result[:repo] = remote_url[/\/(\w|-|\.)+$/i][1..-5]
  elsif remote_url =~ /\Ahttps?/i
    result[:user] = remote_url.split('/')[-2]
    result[:repo] = remote_url.split('/')[-1].gsub(/.git\Z/i, '')
  end

  result
end
parse_first_matching_template_file(template_file_names) click to toggle source
# File lib/git_reflow/git_helpers.rb, line 147
def parse_first_matching_template_file(template_file_names)
  filename = template_file_names.detect do |file|
    File.exist? file
  end

  # Thanks to @Shalmezad for contribuiting the template `gsub` snippet :-)
  # https://github.com/reenhanced/gitreflow/issues/51#issuecomment-253535093
  if filename
    template_content = File.read filename
    template_content.gsub!(/\{\{([a-zA-Z_]+[a-zA-Z0-9_]*)\}\}/) { GitReflow.public_send($1) }
    template_content
  end
end