<commit_before># Gitlab::Git::Repository is a wrapper around native Rugged::Repository object
require 'tempfile'
require 'forwardable'
require "rubygems/package"

module Gitlab
  module Git
    class Repository
      include Gitlab::Git::RepositoryMirroring
      include Gitlab::Git::Popen

      ALLOWED_OBJECT_DIRECTORIES_VARIABLES = %w[
        GIT_OBJECT_DIRECTORY
        GIT_ALTERNATE_OBJECT_DIRECTORIES
      ].freeze
      ALLOWED_OBJECT_RELATIVE_DIRECTORIES_VARIABLES = %w[
        GIT_OBJECT_DIRECTORY_RELATIVE
        GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE
      ].freeze
      SEARCH_CONTEXT_LINES = 3

      NoRepository = Class.new(StandardError)
      InvalidBlobName = Class.new(StandardError)
      InvalidRef = Class.new(StandardError)
      GitError = Class.new(StandardError)
      DeleteBranchError = Class.new(StandardError)
      CreateTreeError = Class.new(StandardError)
      TagExistsError = Class.new(StandardError)

      class << self
        # Unlike `new`, `create` takes the repository path
        def create(repo_path, bare: true, symlink_hooks_to: nil)
          FileUtils.mkdir_p(repo_path, mode: 0770)

          # Equivalent to `git --git-path=#{repo_path} init [--bare]`
          repo = Rugged::Repository.init_at(repo_path, bare)
          repo.close

          if symlink_hooks_to.present?
            hooks_path = File.join(repo_path, 'hooks')
            FileUtils.rm_rf(hooks_path)
            FileUtils.ln_s(symlink_hooks_to, hooks_path)
          end

          true
        end
      end

      # Full path to repo
      attr_reader :path

      # Directory name of repo
      attr_reader :name

      # Relative path of repo
      attr_reader :relative_path

      # Rugged repo object
      attr_reader :rugged

      attr_reader :storage, :gl_repository, :relative_path, :gitaly_resolver

      # This initializer method is only used on the client side (gitlab-ce).
      # Gitaly-ruby uses a different initializer.
      def initialize(storage, relative_path, gl_repository)
        @storage = storage
        @relative_path = relative_path
        @gl_repository = gl_repository
        @gitaly_resolver = Gitlab::GitalyClient

        storage_path = Gitlab.config.repositories.storages[@storage]['path']
        @path = File.join(storage_path, @relative_path)
        @name = @relative_path.split("/").last
        @attributes = Gitlab::Git::Attributes.new(path)
      end

      delegate  :empty?,
                to: :rugged

      def ==(other)
        path == other.path
      end

      # Default branch in the repository
      def root_ref
        @root_ref ||= gitaly_migrate(:root_ref) do |is_enabled|
          if is_enabled
            gitaly_ref_client.default_branch_name
          else
            discover_default_branch
          end
        end
      end

      def rugged
        @rugged ||= circuit_breaker.perform do
          Rugged::Repository.new(path, alternates: alternate_object_directories)
        end
      rescue Rugged::RepositoryError, Rugged::OSError
        raise NoRepository.new('no repository for such path')
      end

      def circuit_breaker
        @circuit_breaker ||= Gitlab::Git::Storage::CircuitBreaker.for_storage(storage)
      end

      def exists?
        Gitlab::GitalyClient.migrate(:repository_exists) do |enabled|
          if enabled
            gitaly_repository_client.exists?
          else
            circuit_breaker.perform do
              File.exist?(File.join(@path, 'refs'))
            end
          end
        end
      end

      # Returns an Array of branch names
      # sorted by name ASC
      def branch_names
        gitaly_migrate(:branch_names) do |is_enabled|
          if is_enabled
            gitaly_ref_client.branch_names
          else
            branches.map(&:name)
          end<commit_msg>Repository Exists check is OPT_OUT for Gitaly<commit_after># Gitlab::Git::Repository is a wrapper around native Rugged::Repository object
require 'tempfile'
require 'forwardable'
require "rubygems/package"

module Gitlab
  module Git
    class Repository
      include Gitlab::Git::RepositoryMirroring
      include Gitlab::Git::Popen

      ALLOWED_OBJECT_DIRECTORIES_VARIABLES = %w[
        GIT_OBJECT_DIRECTORY
        GIT_ALTERNATE_OBJECT_DIRECTORIES
      ].freeze
      ALLOWED_OBJECT_RELATIVE_DIRECTORIES_VARIABLES = %w[
        GIT_OBJECT_DIRECTORY_RELATIVE
        GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE
      ].freeze
      SEARCH_CONTEXT_LINES = 3

      NoRepository = Class.new(StandardError)
      InvalidBlobName = Class.new(StandardError)
      InvalidRef = Class.new(StandardError)
      GitError = Class.new(StandardError)
      DeleteBranchError = Class.new(StandardError)
      CreateTreeError = Class.new(StandardError)
      TagExistsError = Class.new(StandardError)

      class << self
        # Unlike `new`, `create` takes the repository path
        def create(repo_path, bare: true, symlink_hooks_to: nil)
          FileUtils.mkdir_p(repo_path, mode: 0770)

          # Equivalent to `git --git-path=#{repo_path} init [--bare]`
          repo = Rugged::Repository.init_at(repo_path, bare)
          repo.close

          if symlink_hooks_to.present?
            hooks_path = File.join(repo_path, 'hooks')
            FileUtils.rm_rf(hooks_path)
            FileUtils.ln_s(symlink_hooks_to, hooks_path)
          end

          true
        end
      end

      # Full path to repo
      attr_reader :path

      # Directory name of repo
      attr_reader :name

      # Relative path of repo
      attr_reader :relative_path

      # Rugged repo object
      attr_reader :rugged

      attr_reader :storage, :gl_repository, :relative_path, :gitaly_resolver

      # This initializer method is only used on the client side (gitlab-ce).
      # Gitaly-ruby uses a different initializer.
      def initialize(storage, relative_path, gl_repository)
        @storage = storage
        @relative_path = relative_path
        @gl_repository = gl_repository
        @gitaly_resolver = Gitlab::GitalyClient

        storage_path = Gitlab.config.repositories.storages[@storage]['path']
        @path = File.join(storage_path, @relative_path)
        @name = @relative_path.split("/").last
        @attributes = Gitlab::Git::Attributes.new(path)
      end

      delegate  :empty?,
                to: :rugged

      def ==(other)
        path == other.path
      end

      # Default branch in the repository
      def root_ref
        @root_ref ||= gitaly_migrate(:root_ref) do |is_enabled|
          if is_enabled
            gitaly_ref_client.default_branch_name
          else
            discover_default_branch
          end
        end
      end

      def rugged
        @rugged ||= circuit_breaker.perform do
          Rugged::Repository.new(path, alternates: alternate_object_directories)
        end
      rescue Rugged::RepositoryError, Rugged::OSError
        raise NoRepository.new('no repository for such path')
      end

      def circuit_breaker
        @circuit_breaker ||= Gitlab::Git::Storage::CircuitBreaker.for_storage(storage)
      end

      def exists?
        Gitlab::GitalyClient.migrate(:repository_exists, status: Gitlab::GitalyClient::MigrationStatus::OPT_OUT) do |enabled|
          if enabled
            gitaly_repository_client.exists?
          else
            circuit_breaker.perform do
              File.exist?(File.join(@path, 'refs'))
            end
          end
        end
      end

      # Returns an Array of branch names
      # sorted by name ASC
      def branch_names
        gitaly_migrate(:branch_names) do |is_enabled|
          if is_enabled
            gitaly_ref_client.branch_names
          else
            branches.map(&:name)
          end
{'fraction_non_alphanumeric': 0.0754960061839732, 'fraction_numerical': 0.0012883277505797476, 'mean_word_length': 2.370820668693009, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, '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': '638117', 'n_tokens_mistral': 2305, 'n_tokens_neox': 2241, 'n_words': 501}