<commit_before>module MiqToolsServices
  class MiniGit
    include ServiceMixin

    # All MiniGit methods return stdout which always has a trailing newline
    # that is never wanted, so remove it always.
    def delegate_to_service(method_name, *args)
      super.chomp
    end

    attr_reader :path_to_repo

    def initialize(path_to_repo)
      @path_to_repo = path_to_repo
      service # initialize the service
    end

    def service
      @service ||= begin
        require 'minigit'
        ::MiniGit.debug = true
        ::MiniGit::Capturing.new(File.expand_path(path_to_repo))
      end
    end

    def bugzilla_ids(ref)
      Bugzilla.ids_in_git_commit_message(commit_message(ref))
    end

    def temporarily_checkout(ref)
      ref      = ref_name(ref)
      orig_ref = current_branch
      checkout(ref) unless ref == orig_ref
      yield
    ensure
      checkout(orig_ref) unless ref == orig_ref
    end

    def new_commits(since_commit, ref = "HEAD")
      rev_list({:reverse => true}, "#{since_commit}..#{ref}").split("\n")
    end

    def commit_message(commit)
      show({:pretty => "fuller"}, "--stat", "--summary", commit)
    end

    def ref_name(ref)
      name = rev_parse("--abbrev-ref", ref)
      name.empty? ? ref : name
    end

    def author_name(ref)
      log("-1", "--format=\"%an\"", ref)
    end

    def author_email(ref)
      log("-1", "--format=\"%ae\"", ref)
    end

    def subject(ref)
      log("-1", "--format=\"%s\"", ref)
    end

    def current_branch
      ref = ref_name("HEAD")
      ref == "HEAD" ? current_ref : ref
    end

    def current_ref
      rev_parse("HEAD")
    end

    def branches
      branch.split("\n").collect do |b|
        b = b[1..-1] if b.start_with?("*")
        b.strip
      end
    end

    def destroy_branch(branch_name)
      branch("-D", branch_name)
    end

    def diff_details(commit1, commit2 = nil)
      if commit2.nil?
        commit2 = commit1
        commit1 = "#{commit1}~"
      end
      output = diff("--patience", "-U0", "--no-color", "#{commit1}...#{commit2}")

      ret = Hash.new { |h, k| h[k] = [] }
      path = line_number = nil
      output.lines.each_with_object(ret) do |line, h|
        case line
        when /^--- (?:a\/)?/
          next
        when /^\+\+\+ (?:b\/)?(.+)/
          path = $1.chomp
        when /^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/
          line_number = $1.to_i
        when /^([ +-])/
          if $1 != "-"
            h[path] << line_number
            line_number += 1
          end
        end
      end
    end

    def diff_file_names(commit1, commit2 = nil)<commit_msg>Read the difference between two commits one line at a time.<commit_after>module MiqToolsServices
  class MiniGit
    include ServiceMixin

    # All MiniGit methods return stdout which always has a trailing newline
    # that is never wanted, so remove it always.
    def delegate_to_service(method_name, *args)
      super.chomp
    end

    attr_reader :path_to_repo

    def initialize(path_to_repo)
      @path_to_repo = path_to_repo
      service # initialize the service
    end

    def service
      @service ||= begin
        require 'minigit'
        ::MiniGit.debug = true
        ::MiniGit::Capturing.new(File.expand_path(path_to_repo))
      end
    end

    def bugzilla_ids(ref)
      Bugzilla.ids_in_git_commit_message(commit_message(ref))
    end

    def temporarily_checkout(ref)
      ref      = ref_name(ref)
      orig_ref = current_branch
      checkout(ref) unless ref == orig_ref
      yield
    ensure
      checkout(orig_ref) unless ref == orig_ref
    end

    def new_commits(since_commit, ref = "HEAD")
      rev_list({:reverse => true}, "#{since_commit}..#{ref}").split("\n")
    end

    def commit_message(commit)
      show({:pretty => "fuller"}, "--stat", "--summary", commit)
    end

    def ref_name(ref)
      name = rev_parse("--abbrev-ref", ref)
      name.empty? ? ref : name
    end

    def author_name(ref)
      log("-1", "--format=\"%an\"", ref)
    end

    def author_email(ref)
      log("-1", "--format=\"%ae\"", ref)
    end

    def subject(ref)
      log("-1", "--format=\"%s\"", ref)
    end

    def current_branch
      ref = ref_name("HEAD")
      ref == "HEAD" ? current_ref : ref
    end

    def current_ref
      rev_parse("HEAD")
    end

    def branches
      branch.split("\n").collect do |b|
        b = b[1..-1] if b.start_with?("*")
        b.strip
      end
    end

    def destroy_branch(branch_name)
      branch("-D", branch_name)
    end

    def diff_details(commit1, commit2 = nil)
      if commit2.nil?
        commit2 = commit1
        commit1 = "#{commit1}~"
      end
      output = diff("--patience", "-U0", "--no-color", "#{commit1}...#{commit2}")

      ret = Hash.new { |h, k| h[k] = [] }
      path = line_number = nil
      output.each_line do |line|
        case line
        when /^--- (?:a\/)?/
          next
        when /^\+\+\+ (?:b\/)?(.+)/
          path = $1.chomp
        when /^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/
          line_number = $1.to_i
        when /^([ +-])/
          if $1 != "-"
            ret[path] << line_number
            line_number += 1
          end
        end
      end
      ret
    end

    def diff_file_names(commit1, commit2 = nil)
{'fraction_non_alphanumeric': 0.14658596557594097, 'fraction_numerical': 0.00794401361830906, 'mean_word_length': 1.9994327850255247, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2116145', 'n_tokens_mistral': 1808, 'n_tokens_neox': 1755, 'n_words': 415}