You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: repository_spec.rb
    path of file: ./repos/gitlabhq/spec/lib/gitlab/git
    
    the code of the file until where you have to start completion: # frozen_string_literal: true

require "spec_helper"

RSpec.describe Gitlab::Git::Repository, feature_category: :source_code_management do
  include Gitlab::EncodingHelper
  include RepoHelpers
  using RSpec::Parameterized::TableSyntax

  shared_examples 'wrapping gRPC errors' do |gitaly_client_class, gitaly_client_method|
    context 'when commit is not found' do
      let(:find_commits_error) { Gitaly::FindCommitsError.new }

      before do
        allow(Gitlab::GitalyClient).to receive(:decode_detailed_error).and_return(find_commits_error)
      end

      it 'wraps gRPC not found error' do
        expect_any_instance_of(gitaly_client_class).to receive(gitaly_client_method).and_raise(GRPC::NotFound)
        expect { subject }.to raise_error(Gitlab::Git::Repository::CommitNotFound)
      end
    end

    it 'wraps gRPC unknown error' do
      expect_any_instance_of(gitaly_client_class).to receive(gitaly_client_method)
        .and_raise(GRPC::Unknown)
      expect { subject }.to raise_error(Gitlab::Git::CommandError)
    end
  end

  let_it_be(:project) { create(:project, :repository) }
  let_it_be(:repository) { project.repository.raw }

  let(:mutable_project
    
    def create_commit(blobs)
      commit_result = repository.commit_files(
        user,
        branch_name: 'a-new-branch',
        message: 'Add a file',
        actions: blobs.map do |path, content|
          {
            action: :create,
            file_path: path,
            content: content
          }
        end
      )

      # new_blobs only returns unreferenced blobs because it is used for hooks.
      # Gitaly does not allow us to create loose objects via the RPC.
      repository.delete_branch('a-new-branch')

      commit_result.newrev
    end

    subject { repository.new_blobs(newrevs) }

    describe 'memoization' do
      before do
        allow(repository).to receive(:blobs).once.with(["--not", "--all", "--not", "revision1"], kind_of(Hash))
          .and_return(['first result'])
        repository.new_blobs(['revision1'])
      end

      it 'calls blobs only once' do
        expect(repository.new_blobs(['revision1'])).to eq(['first result'])
      end

      context 'when called with a different revision' do
        before do
          allow(repository).to receive(:blobs).once.with(["--not", "--all", "--not", "revision2"], kind_of(Hash))
            .and_return(['second result'])
          repository.new_blobs(['revision2'])
        end

        it 'memoizes the different arguments' do
          expect(repository.new_blobs(['revision2'])).to eq(['second result'])
        end
      end
    end

    shared_examples '#new_blobs with revisions' do
      before do
        expect_next_instance_of(Gitlab::GitalyClient::BlobService) do |service|
          expect(service)
            .to receive(:list_blobs)
            .with(expected_newrevs,
                  limit: Gitlab::Git::Repository::REV_LIST_COMMIT_LIMIT,
                  with_paths: true,
                  dynamic_timeout: nil)
            .once
            .and_call_original
        end
      end

      it 'enumerates new blobs' do
        expect(subject).to match_array(expected_blobs)
      end

      it 'memoizes results' do
        expect(subject).to match_array(expected_blobs)

        # call subject again
        expect(repository.new_blobs(newrevs)).to match_array(expected_blobs)
      end
    end

    context 'with a single revision' do
      let(:newrevs) { commit }
      let(:expected_newrevs) { ['--not', '--all', '--not', newrevs] }
      let(:expected_blobs) do
        [have_attributes(class: Gitlab::Git::Blob, id: an_instance_of(String), path: 'nested/new-blob.txt', size: 18)]
      end

      it_behaves_like '#new_blobs with revisions'
    end

    context 'with a single-entry array' do
      let(:newrevs) { [commit] }
      let(:expected_newrevs) { ['--not', '--all', '--not'] + newrevs }
      let(:expected_blobs) do
        [have_attributes(class: Gitlab::Git::Blob, id: an_instance_of(String), path: 'nested/new-blob.txt', size: 18)]
      end

      it_behaves_like '#new_blobs with revisions'
    end

    context 'with multiple revisions' do
      let(:newrevs) { [commit, create_commit('another_path.txt' => 'Another blob')] }
      let(:expected_newrevs) { ['--not', '--all', '--not'] + newrevs.sort }
      let(:expected_blobs) do
        [
          have_attributes(class: Gitlab::Git::Blob, id: an_instance_of(String), path: 'nested/new-blob.txt', size: 18),
          have_attributes(class: Gitlab::Git::Blob, id: an_instance_of(String), path: 'another_path.txt', size: 12)
        ]
      end

      it_behaves_like '#new_blobs with revisions'
    end

    context 'with partially blank revisions' do
      let(:newrevs) { [nil, commit, Gitlab::Git::SHA1_BLANK_SHA] }
      let(:expected_newrevs) { ['--not', '--all', '--not', commit] }
      let(:expected_blobs) do
        [
          have_attributes(class: Gitlab::Git::Blob, id: an_instance_of(String), path: 'nested/new-blob.txt', size: 18)
        ]
      end

      it_behaves_like '#new_blobs with revisions'
    end

    context 'with repeated revisions' do
      let(:newrevs) { [commit, commit, commit] }
      let(:expected_newrevs) { ['--not', '--all', '--not', commit] }
      let(:expected_blobs) do
        [
          have_attributes(class: Gitlab::Git::Blob, id: an_instance_of(String), path: 'nested/new-blob.txt', size: 18)
        ]
      end

      it_behaves_like '#new_blobs with revisions'
    end

    context 'with preexisting commits' do
      let(:newrevs) { ['refs/heads/master'] }
      let(:expected_newrevs) { ['--not', '--all', '--not'] + newrevs }
      let(:expected_blobs) { [] }

      it_behaves_like '#new_blobs with revisions'
    end

    shared_examples '#new_blobs without revisions' do
      before do
        expect(Gitlab::GitalyClient::BlobService).not_to receive(:new)
      end

      it 'returns an empty array' do
        expect(subject).to eq([])
      end
    end

    context 'with a single nil newrev' do
      let(:newrevs) { nil }

      it_behaves_like '#new_blobs without revisions'
    end

    context 'with a single zero newrev' do
      let(:newrevs) { Gitlab::Git::SHA1_BLANK_SHA }

      it_behaves_like '#new_blobs without revisions'
    end

    context 'with an empty array' do
      let(:newrevs) { [] }

      it_behaves_like '#new_blobs without revisions'
    end

    context 'with array containing only empty refs' do
      let(:newrevs) { [nil, Gitlab::Git::SHA1_BLANK_SHA] }

      it_behaves_like '#new_blobs without revisions'
    end
  end