syntax = "proto3";

package gitaly;

import "lint.proto";
import "packfile.proto";
import "shared.proto";

option go_package = "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb";

// SmartHTTPService is a service that provides RPCs required for HTTP-based Git
// clones via the smart HTTP protocol.
service SmartHTTPService {
  // InfoRefsUploadPack provides the response for GET /info/refs?service=git-upload-pack.
  // It is invoked when the client fetches packs from the server, meaning the server will
  // upload the packs to that client. The client doesn't upload new objects. This is used
  // to advertise the references available on the server to the client via
  // git-upload-pack(1)'s `--advertise-refs` option.
  rpc InfoRefsUploadPack(InfoRefsRequest) returns (stream InfoRefsResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // InfoRefsReceivePack provides the response for GET /info/refs?service=git-receive-pack.
  // It is invoked when the client pushes packs to the server, meaning the server
  // will fetch the packs from the client. This is used to advertise the references
  // available on the server to the client via git-receive-pack(1)'s `--advertise-refs`
  // option.
  rpc InfoRefsReceivePack(InfoRefsRequest) returns (stream InfoRefsResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }


  // PostUploadPackWithSidechannel provides the response for POST /upload-pack. It
  // used to transfer pack files from the server to the client via sidechannels. This
  // is invoked when the client executes `git fetch`.
  //
  // More info on sidechannels: https://gitlab.com/gitlab-org/gitaly/-/blob/master/doc/sidechannel.md
  rpc PostUploadPackWithSidechannel(PostUploadPackWithSidechannelRequest) returns (PostUploadPackWithSidechannelResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // PostReceivePack provides the response for POST /receive-pack. It used to transfer
  // pack files from the client to the server. This is invoked when the client executes `git push`.
  rpc PostReceivePack(stream PostReceivePackRequest) returns (stream PostReceivePackResponse) {
    option (op_type) = {
      op: MUTATOR
    };
  }
}

// InfoRefsRequest is a request for the InfoRefsUploadPack and InfoRefsUploadPack rpcs.
message InfoRefsRequest {
  // repository is the repository on which to operate.
  Repository repository = 1 [(target_repository)=true];
  // git_config_options are parameters to use with git -c (key=value pairs).
  repeated string git_config_options = 2;
  // git_protocol is the git protocol version.
  string git_protocol = 3;
}

// InfoRefsResponse is the response of InfoRefsUploadPack and InfoRefsUploadPack rpcs.
// It is used to provide the client with the servers advertised refs.
message InfoRefsResponse {
  // data is the raw data copied from the stdout of git-upload-pack(1) or
  // git-receive-pack(1) when used with the `--advertise-refs` flag.
  bytes data = 1;
}

// PostUploadPackWithSidechannelRequest is the request for the PostUploadPackWithSidechannel rpc.
message PostUploadPackWithSidechannelRequest {
  // repository is the repository on which to operate.
  Repository repository = 1 [(target_repository)=true];
  // git_config_options are parameters to use with git -c (key=value pairs).
  repeated string git_config_options = 2;
  // git_protocol is the git protocol version.
  string git_protocol = 3;
}

// PostUploadPackWithSidechannelResponse is the response for the PostUploadPackWithSidechannel rpc.
// This is an empty response since the raw data is transferred to the client via the sidechannel
// exclusively.
message PostUploadPackWithSidechannelResponse {
  // packfile_negotiation_statistics is the packfile negotiation statistics.
  PackfileNegotiationStatistics packfile_negotiation_statistics = 1;
}

// PostReceivePackRequest is the request for the PostReceivePack rpc. It is a stream used to
// transfer the raw data from the client to the servers stdin of git-receive-pack(1) process.
message PostReceivePackRequest {
  // repository is the repository on which to operate.
  // It should only be present in the first message of the stream.
  Repository repository = 1 [(target_repository)=true];
  // data is the raw data to be copied to stdin of 'git receive-pack'.
  bytes data = 2;
  // gl_id is the GitLab ID of the user. This is used by Git {pre,post}-receive hooks.
  // It should only be present in the first message of the stream.
  string gl_id = 3;
  // gl_repository refers to the GitLab repository. This is used by Git {pre,post}-receive hooks.
  // It should only be present in the first message of the stream.
  string gl_repository = 4;
  // gl_username is the GitLab Username of the user. This is used by Git {pre,post}-receive hooks.
  // It should only be present in the first message of the stream.
  string gl_username = 5;
  // git_protocol is the git protocol version.
  string git_protocol = 6;
  // git_config_options are parameters to use with git -c (key=value pairs).
  repeated string git_config_options = 7;
}

// PostReceivePackResponse is the response for the PostReceivePack rpc. It is a stream used to
// transfer the raw data from the stdout of git-receive-pack(1) from the server to the client.
message PostReceivePackResponse {
  // data is the raw data from the stdout of 'git receive-pack'.
  bytes data = 1;
}
