BigW Consortium Gitlab

remote_repository.rb 2.84 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
module Gitlab
  module Git
    #
    # When a Gitaly call involves two repositories instead of one we cannot
    # assume that both repositories are on the same Gitaly server. In this
    # case we need to make a distinction between the repository that the
    # call is being made on (a Repository instance), and the "other"
    # repository (a RemoteRepository instance). This is the reason why we
    # have the RemoteRepository class in Gitlab::Git.
    #
    # When you make changes, be aware that gitaly-ruby sub-classes this
    # class.
    #
    class RemoteRepository
      attr_reader :path, :relative_path, :gitaly_repository

      def initialize(repository)
        @relative_path = repository.relative_path
        @gitaly_repository = repository.gitaly_repository

        # These instance variables will not be available in gitaly-ruby, where
        # we have no disk access to this repository.
        @repository = repository
        @path = repository.path
      end

27
      def empty?
28 29
        # We will override this implementation in gitaly-ruby because we cannot
        # use '@repository' there.
30 31 32
        #
        # Caches and memoization used on the Rails side
        !@repository.exists? || @repository.empty?
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
      end

      def commit_id(revision)
        # We will override this implementation in gitaly-ruby because we cannot
        # use '@repository' there.
        @repository.commit(revision)&.sha
      end

      def branch_exists?(name)
        # We will override this implementation in gitaly-ruby because we cannot
        # use '@repository' there.
        @repository.branch_exists?(name)
      end

      # Compares self to a Gitlab::Git::Repository. This implementation uses
      # 'self.gitaly_repository' so that it will also work in the
      # GitalyRemoteRepository subclass defined in gitaly-ruby.
      def same_repository?(other_repository)
        gitaly_repository.storage_name == other_repository.storage &&
          gitaly_repository.relative_path == other_repository.relative_path
      end

      def fetch_env
        gitaly_ssh = File.absolute_path(File.join(Gitlab.config.gitaly.client_path, 'gitaly-ssh'))
        gitaly_address = gitaly_client.address(storage)
        gitaly_token = gitaly_client.token(storage)

        request = Gitaly::SSHUploadPackRequest.new(repository: gitaly_repository)
        env = {
          'GITALY_ADDRESS' => gitaly_address,
          'GITALY_PAYLOAD' => request.to_json,
          'GITALY_WD' => Dir.pwd,
          'GIT_SSH_COMMAND' => "#{gitaly_ssh} upload-pack"
        }
        env['GITALY_TOKEN'] = gitaly_token if gitaly_token.present?

        env
      end

      private

      # Must return an object that responds to 'address' and 'storage'.
      def gitaly_client
        Gitlab::GitalyClient
      end

      def storage
        gitaly_repository.storage_name
      end
    end
  end
end