syntax = "proto3";

package gitaly;

import "google/protobuf/timestamp.proto";
import "lint.proto";
import "shared.proto";

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

// CommitService is a service which provides RPCs that interact with Git
// commits.
service CommitService {

  // ListCommits lists all commits reachable via a set of references by doing a
  // graph walk. This deprecates FindAllCommits and FindCommits (except Follow
  // is not yet supported). Any unknown revisions will cause the RPC to fail.
  rpc ListCommits(ListCommitsRequest) returns (stream ListCommitsResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // ListAllCommits lists all commits present in the repository, including
  // those not reachable by any reference.
  rpc ListAllCommits(ListAllCommitsRequest) returns (stream ListAllCommitsResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc CommitIsAncestor(CommitIsAncestorRequest) returns (CommitIsAncestorResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc TreeEntry(TreeEntryRequest) returns (stream TreeEntryResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc CountCommits(CountCommitsRequest) returns (CountCommitsResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc CountDivergingCommits(CountDivergingCommitsRequest) returns (CountDivergingCommitsResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc GetTreeEntries(GetTreeEntriesRequest) returns (stream GetTreeEntriesResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc ListFiles(ListFilesRequest) returns (stream ListFilesResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc FindCommit(FindCommitRequest) returns (FindCommitResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc CommitStats(CommitStatsRequest) returns (CommitStatsResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // Use a stream to paginate the result set
  rpc FindAllCommits(FindAllCommitsRequest) returns (stream FindAllCommitsResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc FindCommits(FindCommitsRequest) returns (stream FindCommitsResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // CommitLanguages detects the source code languages of the whole tree for a
  // given commit. Returns an error in case no languages could be detected.
  rpc CommitLanguages(CommitLanguagesRequest) returns (CommitLanguagesResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc RawBlame(RawBlameRequest) returns (stream RawBlameResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc LastCommitForPath(LastCommitForPathRequest) returns (LastCommitForPathResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc ListLastCommitsForTree(ListLastCommitsForTreeRequest) returns (stream ListLastCommitsForTreeResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc CommitsByMessage(CommitsByMessageRequest) returns (stream CommitsByMessageResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc ListCommitsByOid(ListCommitsByOidRequest) returns (stream ListCommitsByOidResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc ListCommitsByRefName(ListCommitsByRefNameRequest) returns (stream ListCommitsByRefNameResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc FilterShasWithSignatures(stream FilterShasWithSignaturesRequest) returns (stream FilterShasWithSignaturesResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc GetCommitSignatures(GetCommitSignaturesRequest) returns (stream GetCommitSignaturesResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // This comment is left unintentionally blank.
  rpc GetCommitMessages(GetCommitMessagesRequest) returns (stream GetCommitMessagesResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

  // CheckObjectsExist will check for the existence of revisions against a
  // repository. It returns two sets of data. An array containing the revisions
  // fromm the input that it found on the repository, and an array that contains all
  // revisions from the input it did not find on the repository.
  rpc CheckObjectsExist(stream CheckObjectsExistRequest) returns (stream CheckObjectsExistResponse) {
    option (op_type) = {
      op: ACCESSOR
    };
  }

}

// ListCommitsRequest is a request for the ListCommits RPC.
message ListCommitsRequest {
  // Order is the order in which commits shoud be traversed.
  enum Order {
    // NONE defaults to reverse chronological order.
    NONE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH
    // TOPO order will cause no parents to be shown before all of its children
    // are shown. Furthermore, multiple lines of history will not be
    // intermixed.
    TOPO = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX
    // DATE order will cause no parents to be shown before all of its children
    // are shown. Otherwise, commits are shown in commit timestamp order. This
    // can cause history to be shown intermixed.
    DATE = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX
  };

  // Repository is the repository in which commits should be searched for.
  Repository repository = 1 [(target_repository)=true];

  // Revisions is the set of revisions which should be walked to enumerate
  // commits. Accepts all notation as documented in gitrevisions(7) as well as
  // the pseudo-revisions `--not` and `--all` as documented in git-rev-list(1).
  // Must not be empty.
  repeated string revisions = 2;

  // PaginationParams allows implementation of pagination. The page token is
  // the last commit OID that was sent. It's expected to be the full object ID
  // to guard against ambigious OIDs.
  PaginationParameter pagination_params = 3;

  // Order is the order in which commits should be traversed. Please refer to
  // the enum's documentation for further information.
  Order order = 4;

  // Reverse will cause all commits to be listed in reverse.
  bool reverse = 11;

  // MaxParents will skip all commits which have more than the specified number
  // of parents. If set to `0`, no filtering by parents will happen. If set to
  // `1`, all merge commits will be omitted.
  uint32 max_parents = 5;

  // DisableWalk will disable walking the graph. As a result, only commits
  // which are immediately referenced by Revisions will be returned.
  bool disable_walk = 6;

  // FirstParent will cause the graph walk to only go down the first-parent
  // chain of commits. Merge commits will thus only cause the mainline to be
  // enumerated.
  bool first_parent = 7;

  // After will only list commits which are more recent than the specified date.
  google.protobuf.Timestamp after = 8;

  // After will only list commits which are older than the specified date.
  google.protobuf.Timestamp before = 9;

  // Author will only list commits whose author matches the given pattern,
  // which is a regular expression.
  bytes author = 10;

  // IgnoreCase will apply case-sensitive behaviour while regex matching.
  bool ignore_case = 12;

  // CommitMessagePatterns will only list commits whose commit message matches
  // any of the given patterns.
  repeated bytes commit_message_patterns = 13;
}

// ListCommitsResponse is a response for the ListCommits RPC.
message ListCommitsResponse {
  // Commits is the list of commits found.
  repeated GitCommit commits = 1;
}

// ListAllCommitsRequest is a request for the ListAllCommits RPC.
message ListAllCommitsRequest {
  // Repository is the repository in which commits should be searched for.
  Repository repository = 1 [(target_repository)=true];

  // PaginationParams allows implementation of pagination. The page token is
  // the last commit OID that was sent. It's expected to be the full object ID
  // to guard against ambigious OIDs.
  PaginationParameter pagination_params = 2;
}

// ListAllCommitsResponse is a response for the ListAllCommits RPC.
message ListAllCommitsResponse {
  // Commits is the list of commits found.
  repeated GitCommit commits = 1;
}

// This comment is left unintentionally blank.
message CommitStatsRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  bytes revision = 2;
}

// This comment is left unintentionally blank.
message CommitStatsResponse {
  // OID is the commit. Empty means not found
  string oid = 1;
  // This comment is left unintentionally blank.
  int32 additions = 2;
  // This comment is left unintentionally blank.
  int32 deletions = 3;
}

// This comment is left unintentionally blank.
message CommitIsAncestorRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  string ancestor_id = 2;
  // This comment is left unintentionally blank.
  string child_id = 3;
}

// This comment is left unintentionally blank.
message CommitIsAncestorResponse {
  // This comment is left unintentionally blank.
  bool value = 1;
}

// This comment is left unintentionally blank.
message TreeEntryRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // commit ID or refname
  bytes revision = 2;
  // entry path relative to repository root
  bytes path = 3;
  // Limit is the maximum number of bytes to fetch. If object is bigger, remaining bytes are not sent
  // 0 means there is no limit.
  int64 limit = 4;
  // MaxSize is the maximum allowed object size. If bigger, a FailedPrecondition error is returned
  // 0 means there is no maximum size.
  int64 max_size = 5;
}

// This comment is left unintentionally blank.
message TreeEntryResponse {
  // TODO: Replace this enum with ObjectType in shared.proto
  enum ObjectType {
    // This comment is left unintentionally blank.
    COMMIT = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH
    // This comment is left unintentionally blank.
    BLOB = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX
    // This comment is left unintentionally blank.
    TREE = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX
    // This comment is left unintentionally blank.
    TAG = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX
  }

  // This comment is left unintentionally blank.
  ObjectType type = 1;
  // SHA1 object ID
  string oid = 2;
  // This comment is left unintentionally blank.
  int64 size = 3;
  // file mode
  int32 mode = 4;
  // raw object contents
  bytes data = 5;
}

// This comment is left unintentionally blank.
message CountCommitsRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  bytes revision = 2;
  // This comment is left unintentionally blank.
  google.protobuf.Timestamp after = 3;
  // This comment is left unintentionally blank.
  google.protobuf.Timestamp before = 4;
  // This comment is left unintentionally blank.
  bytes path = 5;
  // This comment is left unintentionally blank.
  int32 max_count = 6;
  // all and revision are mutually exclusive
  bool all = 7;
  // This comment is left unintentionally blank.
  bool first_parent = 8;
  // This comment is left unintentionally blank.
  GlobalOptions global_options = 9;
}

// This comment is left unintentionally blank.
message CountCommitsResponse {
  // This comment is left unintentionally blank.
  int32 count = 1;
}

// This comment is left unintentionally blank.
message CountDivergingCommitsRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  bytes from = 2;
  // This comment is left unintentionally blank.
  bytes to = 3;
  reserved 4;
  reserved 5;
  reserved 6;
  // This comment is left unintentionally blank.
  int32 max_count = 7;
}

// This comment is left unintentionally blank.
message CountDivergingCommitsResponse {
  // This comment is left unintentionally blank.
  int32 left_count = 1;
  // This comment is left unintentionally blank.
  int32 right_count = 2;
}

// This comment is left unintentionally blank.
message TreeEntry {
  // TODO: Replace this enum with ObjectType in shared.proto
  enum EntryType {
    // This comment is left unintentionally blank.
    BLOB = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH
    // This comment is left unintentionally blank.
    TREE = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX
    // This comment is left unintentionally blank.
    COMMIT = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX
  }

  // OID of the object this tree entry points to
  string oid = 1;
  // OID of the tree attached to commit_oid. This field is deprecated and will be removed in Gitaly
  // v16.0 as it cannot be implemented efficiently without having to spawn another extra process
  // that needs to get queried for every single TreeEntry. And at that point the caller can just
  // manually resolve the root tree ID via a separate RPC call, especially so as there are not
  // currently any known users of this feature.
  string root_oid = 2 [deprecated=true];
  // Path relative to repository root
  bytes path = 3;
  // This comment is left unintentionally blank.
  EntryType type = 4;
  // File mode e.g. 0644
  int32 mode = 5;
  // The commit object via which this entry was retrieved
  string commit_oid = 6;
  // Relative path of the first subdir that doesn't have only one directory descendant
  bytes flat_path = 7;
}

// This comment is left unintentionally blank.
message GetTreeEntriesRequest {
  // This comment is left unintentionally blank.
  enum SortBy {
    // Preserve order of git ls-tree.
    DEFAULT = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH
    // Trees, blobs, submodules.
    TREES_FIRST = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX
  }

  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  bytes revision = 2;
  // This comment is left unintentionally blank.
  bytes path = 3;
  // This comment is left unintentionally blank.
  bool recursive = 4;
  // This comment is left unintentionally blank.
  SortBy sort = 5;
  // The page token is the last commit OID that was sent. It's expected to be the
  // full object ID to guard against ambigious OIDs.
  PaginationParameter pagination_params = 6;
  // SkipFlatPath is an option to skip the expensive operation of populating flat paths.
  bool skip_flat_paths = 7;
}

// This comment is left unintentionally blank.
message GetTreeEntriesResponse {
  // This comment is left unintentionally blank.
  repeated TreeEntry entries = 1;
  // This comment is left unintentionally blank.
  PaginationCursor pagination_cursor = 2;
}

// This comment is left unintentionally blank.
message ListFilesRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  bytes revision = 2;
}

// A single 'page' of the paginated response
message ListFilesResponse {
  // Remember to force encoding utf-8 on the client side
  repeated bytes paths = 1;
}

// This comment is left unintentionally blank.
message FindCommitRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  bytes revision = 2;
  // This comment is left unintentionally blank.
  bool trailers = 3;
}

// This comment is left unintentionally blank.
message FindCommitResponse {
  // commit is nil when the commit was not found
  GitCommit commit = 1;
}

// This comment is left unintentionally blank.
message ListCommitsByOidRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  repeated string oid = 2; // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED
}

// This comment is left unintentionally blank.
message ListCommitsByOidResponse {
  // This comment is left unintentionally blank.
  repeated GitCommit commits = 1;
}

// This comment is left unintentionally blank.
message ListCommitsByRefNameRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  repeated bytes ref_names = 2;
}

// This comment is left unintentionally blank.
message ListCommitsByRefNameResponse {
  reserved 1;

  // This comment is left unintentionally blank.
  message CommitForRef {
    // This comment is left unintentionally blank.
    GitCommit commit = 1;
    // This comment is left unintentionally blank.
    bytes ref_name = 2;
  }

  // This comment is left unintentionally blank.
  repeated CommitForRef commit_refs = 2;
}

// This comment is left unintentionally blank.
message FindAllCommitsRequest {
  // This comment is left unintentionally blank.
  enum Order {
    // This comment is left unintentionally blank.
    NONE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH
    // This comment is left unintentionally blank.
    TOPO = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX
    // This comment is left unintentionally blank.
    DATE = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX
  }

  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // When nil, return all commits reachable by any branch in the repo
  bytes revision = 2;
  // This comment is left unintentionally blank.
  int32 max_count = 3;
  // This comment is left unintentionally blank.
  int32 skip = 4;
  // This comment is left unintentionally blank.
  Order order = 5;
}

// A single 'page' of the result set
message FindAllCommitsResponse {
  // This comment is left unintentionally blank.
  repeated GitCommit commits = 1;
}

// This comment is left unintentionally blank.
message FindCommitsRequest {
  // This comment is left unintentionally blank.
  enum Order {
    // This comment is left unintentionally blank.
    NONE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH
    // This comment is left unintentionally blank.
    TOPO = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX
  }

  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  bytes revision = 2;
  // This comment is left unintentionally blank.
  int32 limit = 3;
  // This comment is left unintentionally blank.
  int32 offset = 4;
  // This comment is left unintentionally blank.
  repeated bytes paths = 5;
  // This comment is left unintentionally blank.
  bool follow = 6;
  // This comment is left unintentionally blank.
  bool skip_merges = 7;
  // This comment is left unintentionally blank.
  bool disable_walk = 8;
  // This comment is left unintentionally blank.
  google.protobuf.Timestamp after = 9;
  // This comment is left unintentionally blank.
  google.protobuf.Timestamp before = 10;
  // all and revision are mutually exclusive
  bool all = 11;
  // This comment is left unintentionally blank.
  bool first_parent = 12;
  // This comment is left unintentionally blank.
  bytes author = 13;
  // This comment is left unintentionally blank.
  Order order = 14;
  // This comment is left unintentionally blank.
  GlobalOptions global_options = 15;
  // This comment is left unintentionally blank.
  bool trailers = 16;
  // include_shortstat determines whether to include the number of lines and files
  // changed in the commits. Populates the `short_stats` field.
  bool include_shortstat = 17;
  // include_referenced_by determines whether to include references that point to a
  // commit in the response. The field contains patterns that are matched against
  // references. Only matching references are included in the response. For 
  // example, one can get tags pointing to a commit with `refs/tags`, or branches
  // respectively with `refs/heads`. By sending both, the response will include all
  // references that match either pattern. 
  repeated bytes include_referenced_by = 18; // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED
}

// A single 'page' of the result set
message FindCommitsResponse {
  // This comment is left unintentionally blank.
  repeated GitCommit commits = 1;
}

// CommitLanguagesRequest requests to detect the source code languages.
message CommitLanguagesRequest {
  // Repository is the repository where to detect the languages in.
  Repository repository = 1 [(target_repository)=true];
  // Revision tells for which commit the languages should be detected. If it's
  // omitted, the HEAD commit of the default branch is used.
  bytes revision = 2;
}

// CommitLanguagesResponse returns the language statistics.
message CommitLanguagesResponse {
  // Language specifies the statistics for one language.
  message Language {
    // Name is the name of the detected language, for example: Ruby, Go, HTML
    // A full list of language names can be found at:
    // https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
    string name = 1;
    // Share is the percentual share (value between 0 and 100) of this language
    // in relation to other languages that exist in the given revision.
    float share = 2;
    // Color specifies the associated color for this language, for example #3fd5e0.
    string color = 3;
    // FileCount was a uint32 that stored how many files with this language were found.
    // However, it was never used and there is no client demand for it.
    // See: https://gitlab.com/gitlab-org/gitaly/-/issues/4293.
    reserved 4;
    reserved "file_count";
    // Bytes is the total amount of bytes written in this language
    uint64 bytes = 5;
  }

  // Languages is a set of all the detected languages and their statistics.
  repeated Language languages = 1;
}

// This comment is left unintentionally blank.
message RawBlameRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  bytes revision = 2;
  // This comment is left unintentionally blank.
  bytes path = 3;
  // Comma-separated range of line numbers to perform the blame on: "1,1000".
  // Optional - if no range is provided, the whole file will be blamed.
  bytes range = 4;
}

// This comment is left unintentionally blank.
message RawBlameResponse {
  // This comment is left unintentionally blank.
  bytes data = 1;
}

// This comment is left unintentionally blank.
message LastCommitForPathRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  bytes revision = 2;
  // This comment is left unintentionally blank.
  // This comment is left unintentionally blank.
  // This comment is left unintentionally blank.
  bytes path = 3;
  // This comment is left unintentionally blank.
  bool literal_pathspec = 4; // Deprecate after Rails stops using this
  // This comment is left unintentionally blank.
  GlobalOptions global_options = 5;
}

// This comment is left unintentionally blank.
message LastCommitForPathResponse {
  // commit is nil when the commit was not found
  GitCommit commit = 1;
}

// This comment is left unintentionally blank.
message ListLastCommitsForTreeRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  string revision = 2;
  // This comment is left unintentionally blank.
  bytes path = 3;
  // This comment is left unintentionally blank.
  int32 limit = 4;
  // This comment is left unintentionally blank.
  int32 offset = 5;
  // This comment is left unintentionally blank.
  bool literal_pathspec = 6 [deprecated = true];
  // This comment is left unintentionally blank.
  GlobalOptions global_options = 7;
}

// This comment is left unintentionally blank.
message ListLastCommitsForTreeResponse {
  // This comment is left unintentionally blank.
  message CommitForTree {
    reserved 1;

    // This comment is left unintentionally blank.
    GitCommit commit = 2;
    reserved 3;
    // This comment is left unintentionally blank.
    bytes path_bytes = 4;
  }

  // This comment is left unintentionally blank.
  repeated CommitForTree commits = 1;
}

// This comment is left unintentionally blank.
message CommitsByMessageRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  bytes revision = 2;
  // This comment is left unintentionally blank.
  int32 offset = 3;
  // This comment is left unintentionally blank.
  int32 limit = 4;
  // This comment is left unintentionally blank.
  bytes path = 5;
  // This comment is left unintentionally blank.
  string query = 6;
  // This comment is left unintentionally blank.
  GlobalOptions global_options = 7;
}

// One 'page' of the paginated response of CommitsByMessage
message CommitsByMessageResponse {
  // This comment is left unintentionally blank.
  repeated GitCommit commits = 1;
}

// This comment is left unintentionally blank.
message FilterShasWithSignaturesRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  repeated bytes shas = 2;
}

// This comment is left unintentionally blank.
message FilterShasWithSignaturesResponse {
  // This comment is left unintentionally blank.
  repeated bytes shas = 1;
}

// This comment is left unintentionally blank.
message ExtractCommitSignatureRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  string commit_id = 2;
}

// Either of the 'signature' and 'signed_text' fields may be present. It
// is up to the caller to stitch them together.
message ExtractCommitSignatureResponse {
  // This comment is left unintentionally blank.
  bytes signature = 1;
  // This comment is left unintentionally blank.
  bytes signed_text = 2;
}

// This comment is left unintentionally blank.
message GetCommitSignaturesRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  repeated string commit_ids = 2;
}

// This comment is left unintentionally blank.
message GetCommitSignaturesResponse {
  // Only present for a new commit signature data.
  string commit_id = 1;
  // See ExtractCommitSignatureResponse above for how these fields should be handled.
  bytes signature = 2;
  // This comment is left unintentionally blank.
  bytes signed_text = 3;
}

// This comment is left unintentionally blank.
message GetCommitMessagesRequest {
  // This comment is left unintentionally blank.
  Repository repository = 1 [(target_repository)=true];
  // This comment is left unintentionally blank.
  repeated string commit_ids = 2;
}

// This comment is left unintentionally blank.
message GetCommitMessagesResponse {
  // Only present for a new commit message
  string commit_id = 1;
  // This comment is left unintentionally blank.
  bytes message = 2;
}

// CheckObjectsExistRequest is a request for the CheckObjectsExist RPC. Only
// the initial request must contain a repository, the repository of all
// subsequent requests will be ignored.
message CheckObjectsExistRequest {
  // Repository is the repository in which existence of objects and refs
  // are checked.
  Repository repository = 1 [(target_repository)=true];
  // Revisions contains the revisions that shall be checked for existence. This accepts all revisions
  // as documented in gitrevisions(7)
  repeated bytes revisions = 2;
}

// This comment is left unintentionally blank.
message CheckObjectsExistResponse {
  // This comment is left unintentionally blank.
  message RevisionExistence {
    // This comment is left unintentionally blank.
    bytes name = 1;
    // This comment is left unintentionally blank.
    bool exists = 2;
  };

  // This comment is left unintentionally blank.
  repeated RevisionExistence revisions = 1;
}
