<commit_before>require 'set'

module MGit
  class Repository
    attr_reader :name, :path

    def initialize(name, path)
      @name = name
      @path = path
    end

    def current_branch
      in_repo { 
        b = `git rev-parse --abbrev-ref HEAD 2>&1`.strip 
        $?.exitstatus == 0 ? b : 'HEAD'
      }
    end

    def remote_tracking_branches
      a = in_repo do
        `git for-each-ref --format='%(refname:short) %(upstream:short)' refs/heads`.
          split("\n").
          map { |b| b.split(' ') }.
          reject { |b| b.size != 2 }
      end
      
      Hash[a]
    end

    def flags
      flags = Set.new
      status_lines do |s|
        case s.split[0]
        when 'A'
          flags << :index
        when 'M'
          flags << :dirty
        when '??'
          flags << :untracked
        when '##'
          if /## ([\w,\/]+)\.\.\.([\w,\/]+) \[(\w+) (\d+)\]/ =~ s
            flags << :diverged
          elsif /## HEAD \(no branch\)/ =~ s
            flags << :detached
          end
        end
      end
      flags
    end

    def divergence
      divergence = []
      status_lines do |s|
        if s.split[0] == '##'
          if(m = /## ([\w,\/]+)\.\.\.([\w,\/]+) \[(\w+) (\d+)\]/.match(s))
            if m[3] =~ /behind/
              divergence << { :behind => { :branch => m[2], :by => m[4] } }
            else
              divergence << { :ahead => { :branch => m[2], :by => m[4] } }
            end
          end
        end
      end
      divergence
    end

    def dirty?
      [:index, :dirty, :untracked].any? { |f| flags.include?(f) }
    end

  private
  
    def in_repo
      Dir.chdir(path) { yield }
    end

    def status
      @status ||= in_repo { `git status --short --branch --ignore-submodules`.split("\n") }
    end

    def status_lines
      status.each { |s| yield s }
    end<commit_msg>Repository: Check upstream existence for remote tracking branches.<commit_after>require 'set'

module MGit
  class Repository
    attr_reader :name, :path

    def initialize(name, path)
      @name = name
      @path = path
    end

    def current_branch
      in_repo { 
        b = `git rev-parse --abbrev-ref HEAD 2>&1`.strip 
        $?.exitstatus == 0 ? b : 'HEAD'
      }
    end

    def remote_tracking_branches(upstream_exists_only = true)
      rb = remote_branches

      a = in_repo do
        `git for-each-ref --format='%(refname:short) %(upstream:short)' refs/heads`.
          split("\n").
          map { |b| b.split(' ') }.
          reject { |b| b.size != 2 }.
          select { |b| !upstream_exists_only || rb.include?(b[1]) }
      end
      
      Hash[a]
    end

    def remote_branches
      in_repo do
        `git branch -r`.split("\n").map { |a| a.split(' ')[0] }
      end
    end

    def flags
      flags = Set.new
      status_lines do |s|
        case s.split[0]
        when 'A'
          flags << :index
        when 'M'
          flags << :dirty
        when '??'
          flags << :untracked
        when '##'
          if /## ([\w,\/]+)\.\.\.([\w,\/]+) \[(\w+) (\d+)\]/ =~ s
            flags << :diverged
          elsif /## HEAD \(no branch\)/ =~ s
            flags << :detached
          end
        end
      end
      flags
    end

    def divergence
      divergence = []
      status_lines do |s|
        if s.split[0] == '##'
          if(m = /## ([\w,\/]+)\.\.\.([\w,\/]+) \[(\w+) (\d+)\]/.match(s))
            if m[3] =~ /behind/
              divergence << { :behind => { :branch => m[2], :by => m[4] } }
            else
              divergence << { :ahead => { :branch => m[2], :by => m[4] } }
            end
          end
        end
      end
      divergence
    end

    def dirty?
      [:index, :dirty, :untracked].any? { |f| flags.include?(f) }
    end

  private

    def in_repo
      Dir.chdir(path) { yield }
    end

    def status
      @status ||= in_repo { `git status --short --branch --ignore-submodules`.split("\n") }
    end

    def status_lines
      status.each { |s| yield s }
    end
{'fraction_non_alphanumeric': 0.1697645600991326, 'fraction_numerical': 0.005947955390334572, 'mean_word_length': 1.4138755980861244, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 17, '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': '6502028', 'n_tokens_mistral': 1407, 'n_tokens_neox': 1353, 'n_words': 339}