ruby 确定已合并到另一个分支的孤立分支。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ruby 确定已合并到另一个分支的孤立分支。相关的知识,希望对你有一定的参考价值。

#!/usr/bin/env ruby
#
# Get a list of merged branches
#
# You need to checkout the target remote branch before running. In other words,
# if your target branch is 'master', you have to have it on your local hard disk
# before you run this script, otherwise you will get an error like: `fatal:
# malformed object name master`. Git needs to have the branch available locally
# with latest changes pulled in order to find the branches that have/have-not
# been merged into it.
#
# To create a list of branch-names only, without date info
#
# git-merged-branches.rb --branch production --exclude-days 180 | cut -f1 -d'|'
#
# For help run: git-merged-branches.rb --help

require 'trollop'
require 'fileutils'
require 'colored'
require 'pry'

class GitMergedBranches
  attr_accessor :branch_count, :options, :elapsed, :excluded_branches, :matched_count

  include FileUtils

  class BranchEntry
    attr_accessor :name, :last_commit_date, :relative_last_commit, :last_commiter

    def initialize(name, last_commit_date, relative_last_commit, last_commiter)
      self.name = name
      self.last_commit_date = last_commit_date
      self.relative_last_commit = relative_last_commit
      self.last_commiter = last_commiter
    end

    def <=>(other)
      last_commit_date <=> other.last_commit_date
    end

    def to_s
      "#{name} | #{last_commit_date} | #{relative_last_commit} by #{last_commiter}"
    end
  end

  class << self
    def collect_args(*_args)
      opts = Trollop.options do
        opt(
          :branch,
          'Base branch - list branches merged into this branch. Uses current branch if not specified.',
          type: :string, short: 'b', required: false
        )
        opt(
          :exclude_days,
          'Exclude branches that have no commits within this many days',
          type: :integer, short: 'x', required: false, default: 0
        )
        opt(
          :color,
          'Use colored output',
          type: :boolean, short: 'c', required: false, default: true
        )
      end
      # Set branch to current if not given on command line
      opts[:branch] ||= `git rev-parse --abbrev-ref HEAD`.chomp
      opts
    end

    def run
      start_time = Time.now
      opts = collect_args(ARGV)

      instance = GitMergedBranches.new(opts)
      instance.process
      instance.elapsed = Time.now - start_time
      instance.report_summary
    end
  end

  def initialize(opts)
    self.branch_count = 0
    self.excluded_branches = []
    self.options = opts
  end

  def color(string, clr)
    if options[:color]
      puts(string.send(clr))
    else
      puts(string)
    end
  end

  def report_summary
    puts
    color(">>> Processed #{branch_count} branches in [#{elapsed}] seconds", :red)
    color(">>> Branches with NO commits in the last #{options[:exclude_days]} days: [#{matched_count}]", :red)
    color(">>> Branches with commits in the last #{options[:exclude_days]} days: [#{excluded_branches.count}]", :red)
  end

  def process
    self.matched_count = matched_branches.count
    color(">>> #{matched_count} remote branches that have been merged into `#{options[:branch]}` with no commits in the last #{options[:exclude_days]} days:", :green)
    puts
    puts matched_branches.sort
  end

  def merged_branches
    @branches ||= begin
      current_origin = nil
      cmd = "git branch -r --merged #{options[:branch]}"
      merged_list = `#{cmd}`.split("\n").collect(&:strip)
      raise "Error running: #{cmd}. See output above ^^^" unless $?.exitstatus == 0
      # find and delete the HEAD pointer and current branch origin
      head_pointer = merged_list.grep(/ -> /).first
      current_origin = head_pointer.split(/ -> /).last if head_pointer
      merged_list.delete_if { |elem| [head_pointer, current_origin].include?(elem) }
    end
  end

  def matched_branches
    today = Date.today
    @sorted ||= merged_branches.map do |branch|
      self.branch_count += 1
      date_strings = `git show --format="%ci|%cr" #{branch} | head -n 1`.chomp.split('|')
      last_commit_date = Date.strptime(date_strings.first, '%Y-%m-%d')
      days_old = (today - last_commit_date).to_i
      if recent_branch?(days_old)
        excluded_branches << branch
        nil
      else
        BranchEntry.new(branch, last_commit_date, date_strings.last, last_commiter(branch))
      end
    end.compact
  end

  # Determine if a branch has any commits within the last options[:exclude_days] days
  def recent_branch?(branch_age)
    branch_age.to_i <= options[:exclude_days].to_i
  end

  def last_commiter(branch)
    cmd = %(git show --format="%ai %ar by %an" #{branch} | head -n 1)
    data = `#{cmd}`.split
    data.last
  end
end

GitMergedBranches.run

以上是关于ruby 确定已合并到另一个分支的孤立分支。的主要内容,如果未能解决你的问题,请参考以下文章

ruby 用于列出已合并到指定分支的所有远程分支的脚本。 (可选)使用最近提交排除分支。书面

使用 Git 将未合并的功能分支合并到另一个功能分支

Git 在将两个分支合并到主(主)分支之前将一个开发人员分支合并到另一个开发人员分支

如何在SVN中从一个分支合并到另一个分支并再次返回(双向合并)?

git 合并某分支某次commit到另一个分支

git把一个分支上的某个提交合并到另一个分支