main 81ede3b

merge_request.proto RawHistoryFolder

1// SPDX-License-Identifier: MIT
2
3syntax = "proto3";
4
5package ermite;
6
7import "ermite/git.proto";
8import "ermite/types.proto";
9import "google/protobuf/timestamp.proto";
10
11// MergeRequestState is where a merge request is in its life.
12enum MergeRequestState {
13  // Not set. In ListMergeRequestsRequest.state it means every state. Never
14  // returned by the server.
15  MERGE_REQUEST_STATE_UNSPECIFIED = 0;
16  // The merge request awaits review; it can be commented on, merged or closed.
17  MERGE_REQUEST_STATE_OPEN = 1;
18  // The source branch was merged into the target. Final.
19  MERGE_REQUEST_STATE_MERGED = 2;
20  // The merge request was closed without merging. Final.
21  MERGE_REQUEST_STATE_CLOSED = 3;
22}
23
24// DiffSide is the side of a diff a line comment is attached to.
25enum DiffSide {
26  // Not set. On a Comment it means the comment is general, not attached to a
27  // line. In AddCommentRequest it is valid only for a general comment.
28  DIFF_SIDE_UNSPECIFIED = 0;
29  // The old side: the line is a Line.old_number (a deletion or a context line).
30  DIFF_SIDE_OLD = 1;
31  // The new side: the line is a Line.new_number (an addition or a context
32  // line).
33  DIFF_SIDE_NEW = 2;
34}
35
36// Verdict is the judgement a reviewer gives with a comment.
37enum Verdict {
38  // Not set. The comment carries no verdict. In AddCommentRequest it means a
39  // plain comment.
40  VERDICT_UNSPECIFIED = 0;
41  // The reviewer approves the merge request. The comment is created resolved.
42  VERDICT_APPROVE = 1;
43  // The reviewer asks for changes. The comment starts unresolved.
44  VERDICT_CHANGES_REQUESTED = 2;
45}
46
47// MergeabilityState tells whether the head of an open merge request can be
48// merged into its target.
49enum MergeabilityState {
50  // Not set.
51  MERGEABILITY_STATE_UNSPECIFIED = 0;
52  // The server has no result yet for the current tips of both branches. It
53  // is replaced by another state when the check completes.
54  MERGEABILITY_STATE_CHECKING = 1;
55  // The target is an ancestor of the head: every mode can merge.
56  MERGEABILITY_STATE_UP_TO_DATE = 2;
57  // The target has commits the head lacks, but the head merges cleanly:
58  // squash and merge commit can merge, fast-forward cannot.
59  MERGEABILITY_STATE_BEHIND = 3;
60  // The head does not merge cleanly into the target, or the branches share no
61  // history: no mode can merge.
62  MERGEABILITY_STATE_CONFLICT = 4;
63}
64
65// Mergeability is the result of checking an open merge request against the
66// tips of its branches.
67message Mergeability {
68  // State is the result.
69  MergeabilityState state = 1;
70  // TargetId is the commit the target branch pointed to when checked. Empty
71  // while CHECKING.
72  string target_id = 2;
73  // HeadId is the commit the source branch pointed to when checked. Empty
74  // while CHECKING.
75  string head_id = 3;
76  // Behind is the number of commits of the target that the head lacks. Set
77  // only when state is BEHIND.
78  int32 behind = 4;
79  // BehindCapped says that Behind is a lower bound: the server stops counting
80  // at 1,000.
81  bool behind_capped = 5;
82  // ConflictPaths are the paths that conflict, at most 20. Set only when
83  // state is CONFLICT; empty when the branches share no history.
84  repeated string conflict_paths = 6;
85  // ConflictPathsTruncated says that more paths conflict than listed.
86  bool conflict_paths_truncated = 7;
87  // CheckedAt is when the server computed the result. Unset while CHECKING.
88  google.protobuf.Timestamp checked_at = 8;
89}
90
91// AutoMerge is the pending auto-merge of an open merge request: the server
92// merges it by itself once its checks pass. Set only by servers with the
93// "merge_requests.auto_merge" feature.
94message AutoMerge {
95  // Mode is the merge mode used. Never MERGE_MODE_UNSPECIFIED.
96  MergeMode mode = 1;
97  // HeadId is the head the auto-merge was enabled for. A new head cancels the
98  // auto-merge.
99  string head_id = 2;
100  // EnabledBy names who enabled the auto-merge, like MergeRequest.author.
101  string enabled_by = 3;
102  // EnabledAt is when the auto-merge was enabled.
103  google.protobuf.Timestamp enabled_at = 4;
104}
105
106// MergeRequest asks to merge one branch of a repository into another branch
107// of the same repository. It is about a branch, not about who wrote it.
108message MergeRequest {
109  // Repo is the name of the repository.
110  string repo = 1;
111  // Number identifies the merge request within its repository, starting at 1
112  // and never reused. It is written "!<number>" in messages and URLs.
113  int64 number = 2;
114  // Title is a one-line plain-text title, at most 120 characters.
115  string title = 3;
116  // Description is a plain-text description, at most 8,000 characters. It may
117  // be empty. Clients show it escaped, with line breaks kept.
118  string description = 4;
119  // SourceBranch is the short name of the branch to merge, for example
120  // "feat/x".
121  string source_branch = 5;
122  // TargetBranch is the short name of the branch to merge into, for example
123  // "main".
124  string target_branch = 6;
125  // State is where the merge request is in its life.
126  MergeRequestState state = 7;
127  // Author names who created the merge request: the label of the token that
128  // was used, "root" for the root token, or "owner" for a web session. It is
129  // informational: labels are not unique and the token may be gone.
130  string author = 8;
131  // CreatedAt is when the merge request was created.
132  google.protobuf.Timestamp created_at = 9;
133  // UpdatedAt is when the merge request last changed: title, description,
134  // state, or a comment added or resolved. Pushes to the source branch do not
135  // change it.
136  google.protobuf.Timestamp updated_at = 10;
137  // HeadId is the id of the commit the source branch points to. While the
138  // merge request is open it is read from Git at every call, so it changes
139  // when the branch is pushed; it is empty if the branch was deleted. Once
140  // merged or closed it is the head at that moment.
141  string head_id = 11;
142  // MergedCommitId is the id of the commit the target branch points to after
143  // the merge: the head for a fast-forward, the new commit for a squash or a
144  // merge commit.
145  // Empty unless state is MERGED.
146  string merged_commit_id = 12;
147  // MergeMode is how the merge request was merged. MERGE_MODE_UNSPECIFIED
148  // unless state is MERGED.
149  MergeMode merge_mode = 13;
150  // Mergeability tells whether the head can be merged into the target. Set
151  // while the merge request is OPEN, with state CHECKING until the server has
152  // a result for the current tips; never set once merged or closed. It is a
153  // hint: MergeMergeRequest checks again. Set only by servers with the
154  // "merge_requests.mergeability" feature.
155  Mergeability mergeability = 14;
156  // AutoMerge is the pending auto-merge. Set only while the merge request is
157  // OPEN and auto-merge is enabled; unset once merged or closed. Set only by
158  // servers with the "merge_requests.auto_merge" feature.
159  AutoMerge auto_merge = 15;
160  // AutoMerged is true when the server merged the merge request by auto-merge.
161  // Always false unless state is MERGED.
162  bool auto_merged = 16;
163}
164
165// Comment is a note on a merge request, either general or attached to a line
166// of its diff.
167message Comment {
168  // Id identifies the comment within its merge request. Opaque.
169  string id = 1;
170  // Author names who wrote the comment, like MergeRequest.author.
171  string author = 2;
172  // Path is the path of the commented file in the diff (the new path, or the
173  // old path of a deleted file). Empty for a general comment.
174  string path = 3;
175  // Line is the 1-based line number on side. 0 for a general comment.
176  int32 line = 4;
177  // Side tells whether line counts on the old or the new side of the diff.
178  // DIFF_SIDE_UNSPECIFIED for a general comment.
179  DiffSide side = 5;
180  // CommitId is the head of the merge request when the comment was written.
181  // When it differs from the current head the line may have moved; clients
182  // may show the comment as outdated.
183  string commit_id = 6;
184  // Text is the Markdown source, at most 8,000 characters. Clients render it
185  // as Markdown without raw HTML; "^<id>" refers to a note of the same merge
186  // request. Empty when deleted is true, and possibly empty for a comment
187  // that carries a verdict.
188  string text = 7;
189  // Resolved is true once the comment was marked resolved.
190  bool resolved = 8;
191  // CreatedAt is when the comment was written.
192  google.protobuf.Timestamp created_at = 9;
193  // ReplyTo is the id of the root comment this comment replies to. Empty for
194  // a root comment. A reply has the path, line, start_line and side of its
195  // root, and its commit_id is the head when the reply was written. Threads
196  // have one level: a reply never has replies.
197  string reply_to = 10;
198  // StartLine is the 1-based first line of a range that ends at line, on the
199  // same side. 0 for a comment on a single line or a general comment.
200  int32 start_line = 11;
201  // Verdict is the judgement given with the comment. Only a root comment has
202  // one; it never changes after creation.
203  Verdict verdict = 12;
204  // EditedAt is when the text was last changed or the comment was deleted.
205  // Unset if it never was.
206  google.protobuf.Timestamp edited_at = 13;
207  // Deleted is true once the author deleted the comment. Its text is then
208  // empty; its id, anchor, replies and verdict remain.
209  bool deleted = 14;
210}
211
212// AuthorVerdict is the current verdict of one author on a merge request: the
213// one given with the author's latest comment that carries a verdict.
214message AuthorVerdict {
215  // Author names who gave the verdict, like Comment.author.
216  string author = 1;
217  // Verdict is the current verdict. Never VERDICT_UNSPECIFIED.
218  Verdict verdict = 2;
219  // CommentId is the id of the comment that carries the verdict.
220  string comment_id = 3;
221  // CommitId is the head of the merge request when the verdict was given.
222  string commit_id = 4;
223  // CreatedAt is when the verdict was given.
224  google.protobuf.Timestamp created_at = 5;
225  // Stale is true for an approval given on a commit that is not the current
226  // head. A request for changes is never stale.
227  bool stale = 6;
228}
229
230// MergeRequestService reviews and merges branches.
231//
232// Every RPC takes the repository name and, except for creation and listing,
233// the merge request number. A repository that does not exist or that the
234// caller cannot read gives not_found; so does an unknown number. Reading
235// (ListMergeRequests, GetMergeRequest) needs the same access as reading the
236// repository: nothing for a public one, the repo:read scope for a private
237// one. Writing needs a scope on the repository, given per RPC; a caller
238// without it gets permission_denied.
239//
240// Text fields follow the same rules everywhere: valid UTF-8, no control
241// characters (except the line break in description and comment text) and no
242// Unicode bidirectional override or isolate characters; title is one line of
243// at most 120 characters, description and comment text at most 8,000
244// characters. A request that breaks a rule is rejected whole with
245// invalid_argument, and the error carries a BadRequest detail naming the
246// fields.
247//
248// Servers that implement this service list "merge_requests" in
249// GetVersionResponse.features.
250service MergeRequestService {
251  // CreateMergeRequest opens a merge request. Needs the mr:write scope. Fails
252  // with invalid_argument if a text rule is broken, if a branch does not exist
253  // or if source and target are the same branch, and with already_exists if an
254  // open merge request already has the same source and target.
255  rpc CreateMergeRequest(CreateMergeRequestRequest) returns (CreateMergeRequestResponse);
256  // ListMergeRequests lists the merge requests of a repository, highest
257  // number (newest) first, optionally restricted to one state. The listed
258  // merge requests carry no diff or comments; head_id is set. Fails with
259  // not_found if the repository does not exist or is not readable.
260  rpc ListMergeRequests(ListMergeRequestsRequest) returns (ListMergeRequestsResponse);
261  // GetMergeRequest returns one merge request with its commits, its diff and
262  // its comments. The diff compares the target with the head (what the merge
263  // would bring: "target...head"), or, with since_last_read, the head the
264  // caller last marked read with the current head. Fails with not_found if
265  // the repository or the number is unknown.
266  rpc GetMergeRequest(GetMergeRequestRequest) returns (GetMergeRequestResponse);
267  // AddComment adds a general comment, a comment on a line or a range of
268  // lines of the diff, or a reply to a root comment. Needs the mr:write
269  // scope; setting a verdict also needs the mr:review scope (permission_denied
270  // without it). Fails with invalid_argument if the text breaks a rule (it may
271  // be empty only with a verdict), if path, line, start_line and side do not
272  // designate lines of the current diff of the merge request, if reply_to is
273  // not the id of a root comment that is not deleted, if a reply sets path,
274  // line, start_line, side or verdict, or if a verdict is set on a reply; and
275  // with failed_precondition if the merge request is not open. A comment with
276  // VERDICT_APPROVE is created resolved.
277  rpc AddComment(AddCommentRequest) returns (AddCommentResponse);
278  // EditComment replaces the text of a comment. Needs the mr:write scope, and
279  // only the author of the comment can edit it (permission_denied
280  // otherwise). Fails with invalid_argument if the text breaks a rule (it may
281  // be empty only for a comment with a verdict), with not_found if the comment
282  // is unknown, and with failed_precondition if the merge request is not open
283  // or the comment was deleted. Sending the current text succeeds and changes
284  // nothing.
285  rpc EditComment(EditCommentRequest) returns (EditCommentResponse);
286  // DeleteComment deletes a comment: its text is emptied and deleted is set,
287  // while its id, anchor, replies and verdict remain. Needs the mr:write
288  // scope, and only the author of the comment can delete it
289  // (permission_denied otherwise). Fails with not_found if the comment is
290  // unknown and with failed_precondition if the merge request is not open.
291  // Deleting a comment already deleted succeeds and changes nothing.
292  rpc DeleteComment(DeleteCommentRequest) returns (DeleteCommentResponse);
293  // ResolveComment marks a thread resolved or unresolved. Needs the mr:write
294  // scope. Resolution belongs to the root comment: on a reply it fails with
295  // invalid_argument. Fails with not_found if the comment is unknown and with
296  // failed_precondition if the merge request is not open. Setting the state
297  // the comment already has succeeds and changes nothing.
298  rpc ResolveComment(ResolveCommentRequest) returns (ResolveCommentResponse);
299  // CloseMergeRequest closes an open merge request without merging it. Needs
300  // the mr:write scope. Fails with failed_precondition if the merge request
301  // is not open. A closed merge request cannot be reopened: open a new one.
302  rpc CloseMergeRequest(CloseMergeRequestRequest) returns (CloseMergeRequestResponse);
303  // MarkReady removes the draft prefix ("WIP:" or "[WIP]") from the title so
304  // the merge request can be merged. Needs the mr:write scope. Fails with
305  // failed_precondition if the merge request is not open or is not a draft.
306  // Publishes no event: there is none for a change of title. Needs the
307  // "merge_requests.ready" feature.
308  rpc MarkReady(MarkReadyRequest) returns (MarkReadyResponse);
309  // MergeMergeRequest merges an open merge request. Needs the mr:merge scope,
310  // which merges only when the checks on the head allow it: none failed and
311  // none queued or running (a head with no checks may be merged; success,
312  // skipped and neutral pass). The mr:force-merge scope allows ignore_checks.
313  // The caller passes the head it reviewed: the server merges only if the
314  // source branch still points to it, so a push between review and merge is
315  // never merged unseen. Fails with invalid_argument if head_id is empty or
316  // not a commit id, and with failed_precondition if the merge request is not
317  // open, if the source branch no longer points to head_id ("branch moved,
318  // read again"), if the mode is fast-forward and the target is not an
319  // ancestor of the head (rebase and push again, or merge with squash or
320  // merge commit), if the mode is squash or merge commit and the head
321  // conflicts with the target or shares no history with it (rebase and push
322  // again), if the mode is not allowed by RepoSettings, or if a check failed or
323  // has not finished, unless ignore_checks is set. Merges of one
324  // repository run one at a time. Repeating a call that succeeded fails with
325  // failed_precondition (not open). On success the server publishes
326  // MergeRequestMerged then Pushed for the target branch.
327  rpc MergeMergeRequest(MergeMergeRequestRequest) returns (MergeMergeRequestResponse);
328  // EnableAutoMerge asks the server to merge an open merge request by itself
329  // once at least one check passed on its head, every run created on that head
330  // is complete, and no check failed. It does not take ignore_checks. Needs
331  // the mr:merge scope and, for a token limited to branches, write access to
332  // the target branch
333  // (permission_denied otherwise). The server records the caller, the mode and
334  // the head the caller saw; it merges as the caller, after resolving the caller
335  // again, and cancels the auto-merge if the caller can no longer merge, if the
336  // mode is no longer allowed, if the source branch moves or if the setting is
337  // turned off. Fails with invalid_argument if the mode is not a merge mode or
338  // if head_id is empty or not a commit id, and with failed_precondition if the
339  // merge request is not open, if the source branch no longer points to head_id
340  // ("branch moved, read again"), is a draft,
341  // RepoSettings.allow_auto_merge is off, the mode is not allowed by
342  // RepoSettings, or the server has no CI. Enabling again replaces the mode.
343  // Publishes MergeRequestAutoMergeEnabled. Needs the
344  // "merge_requests.auto_merge" feature.
345  rpc EnableAutoMerge(EnableAutoMergeRequest) returns (EnableAutoMergeResponse);
346  // CancelAutoMerge cancels the pending auto-merge of an open merge request.
347  // Needs the mr:merge scope and, for a token limited to branches, write access
348  // to the target branch. Fails with failed_precondition if auto-merge is not
349  // enabled. Publishes MergeRequestAutoMergeCancelled.
350  rpc CancelAutoMerge(CancelAutoMergeRequest) returns (CancelAutoMergeResponse);
351  // MarkRead records the head the caller has reviewed, for the since_last_read
352  // option of GetMergeRequest. There is one read position per merge request,
353  // the reviewer's. Needs the mr:write scope. Marking a commit that does not
354  // exist in the repository is invalid_argument.
355  rpc MarkRead(MarkReadRequest) returns (MarkReadResponse);
356}
357
358// CreateMergeRequestRequest describes the merge request to open.
359message CreateMergeRequestRequest {
360  // Repo is the repository name.
361  string repo = 1;
362  // Title is the one-line title. Required.
363  string title = 2;
364  // Description is the optional description.
365  string description = 3;
366  // SourceBranch is the short name of the branch to merge. Required; the
367  // branch must exist.
368  string source_branch = 4;
369  // TargetBranch is the short name of the branch to merge into. Empty means
370  // the default branch of the repository. The branch must exist and differ
371  // from source_branch.
372  string target_branch = 5;
373}
374
375// CreateMergeRequestResponse holds the new merge request.
376message CreateMergeRequestResponse {
377  // MergeRequest is the created merge request.
378  MergeRequest merge_request = 1;
379}
380
381// ListMergeRequestsRequest selects a page of merge requests.
382message ListMergeRequestsRequest {
383  // Repo is the repository name.
384  string repo = 1;
385  // State restricts the result to one state. MERGE_REQUEST_STATE_UNSPECIFIED
386  // means every state.
387  MergeRequestState state = 2;
388  // PageSize is the maximum number of merge requests to return. 0 means the
389  // server default; values above the server maximum are lowered to it.
390  int32 page_size = 3;
391  // PageToken is the next_page_token of a previous response, to continue the
392  // same listing. Empty for the first page. Other fields must be unchanged.
393  string page_token = 4;
394}
395
396// ListMergeRequestsResponse is one page of merge requests.
397message ListMergeRequestsResponse {
398  // MergeRequests are the merge requests of this page, highest number first.
399  repeated MergeRequest merge_requests = 1;
400  // NextPageToken is passed as page_token to get the next page. Empty when
401  // there is no next page.
402  string next_page_token = 2;
403}
404
405// MergeRequestIssueState is where an issue named by a merge request is in its
406// life. Values share their numbers with IssueState (3, awaiting moderation,
407// is never shown here). It exists because issue.proto imports this file and
408// cannot be imported back.
409enum MergeRequestIssueState {
410  // Not set. Never returned by the server.
411  MERGE_REQUEST_ISSUE_STATE_UNSPECIFIED = 0;
412  // The issue is open.
413  MERGE_REQUEST_ISSUE_STATE_OPEN = 1;
414  // The issue is closed without being resolved.
415  MERGE_REQUEST_ISSUE_STATE_CLOSED = 2;
416  // The issue was resolved, by a merge or by hand.
417  MERGE_REQUEST_ISSUE_STATE_RESOLVED = 4;
418}
419
420// MergeRequestIssue is an issue of the same repository that a merge request
421// names ("#N").
422message MergeRequestIssue {
423  // Number is the number of the issue.
424  int64 number = 1;
425  // Title is the title of the issue.
426  string title = 2;
427  // State is where the issue is in its life.
428  MergeRequestIssueState state = 3;
429  // Closes says that a closing reference names the issue: merging the request
430  // resolves it.
431  bool closes = 4;
432}
433
434// IssueEventKind is what happened in an IssueEvent.
435enum IssueEventKind {
436  // Not set. Never returned by the server.
437  ISSUE_EVENT_KIND_UNSPECIFIED = 0;
438  // A merge request started naming the issue; closes says whether with a
439  // closing reference.
440  ISSUE_EVENT_KIND_REFERENCED = 1;
441  // The issue was closed without being resolved.
442  ISSUE_EVENT_KIND_CLOSED = 2;
443  // The issue was reopened.
444  ISSUE_EVENT_KIND_REOPENED = 3;
445  // The issue was resolved; merge_request is set when a merge resolved it.
446  ISSUE_EVENT_KIND_RESOLVED = 4;
447}
448
449// IssueEvent is one entry in the history of an issue. Events are append-only:
450// a reference that later disappears does not remove its event.
451message IssueEvent {
452  // Id identifies the event within its issue. Opaque. Events of different
453  // issues can share an id: key them by (issue, id).
454  string id = 1;
455  // Kind is what happened.
456  IssueEventKind kind = 2;
457  // Issue is the number of the issue.
458  int64 issue = 3;
459  // MergeRequest is the number of the merge request involved; 0 if none.
460  int64 merge_request = 4;
461  // MergeRequestTitle is the title of that merge request at read time; empty
462  // if none.
463  string merge_request_title = 5;
464  // Closes says that the reference was a closing one. Only set for
465  // ISSUE_EVENT_KIND_REFERENCED.
466  bool closes = 6;
467  // Actor names who caused the event, like Issue.author: the label of the
468  // token or session. For events triggered by a merge, the label of who
469  // merged.
470  string actor = 7;
471  // CreatedAt is when the event happened.
472  google.protobuf.Timestamp created_at = 8;
473}
474
475// GetMergeRequestRequest selects a merge request.
476message GetMergeRequestRequest {
477  // Repo is the repository name.
478  string repo = 1;
479  // Number is the merge request number.
480  int64 number = 2;
481  // SinceLastRead asks for the diff between the head recorded by MarkRead and
482  // the current head instead of the diff against the target. It works after a
483  // force-push as long as the recorded commit still exists in the repository.
484  // When nothing was marked read, or the recorded commit is gone, the response
485  // holds the diff against the target and says so in last_read_id and
486  // last_read_lost.
487  bool since_last_read = 3;
488}
489
490// GetMergeRequestResponse holds a merge request with its review data.
491message GetMergeRequestResponse {
492  // MergeRequest is the merge request.
493  MergeRequest merge_request = 1;
494  // Commits are the commits of the head that are not in the target
495  // ("target..head"), newest first. At most 100 are returned (a server limit
496  // that may change; rely on commits_truncated, not on the number). Empty when
497  // the source branch was deleted.
498  repeated Commit commits = 2;
499  // CommitsTruncated is true when the branch has more commits than commits
500  // holds.
501  bool commits_truncated = 3;
502  // DiffBaseId is the id of the commit the diff compares from: the merge base
503  // of the target and the head, or the last read head when since_last_read
504  // applied. Empty when the source branch was deleted; diff is then empty.
505  string diff_base_id = 4;
506  // Stats are the totals of the diff, including files that it omits or
507  // truncates.
508  DiffStats stats = 5;
509  // Diff is the structured diff from diff_base_id to the head, with the same
510  // limits and truncated flags as GetCommitResponse.diff.
511  Diff diff = 6;
512  // Comments are every comment of the merge request, oldest first.
513  repeated Comment comments = 7;
514  // LastReadId is the head recorded by MarkRead, whether or not
515  // since_last_read was set. Empty when nothing was marked read.
516  string last_read_id = 8;
517  // LastReadLost is true when since_last_read was set, a head was recorded,
518  // but that commit no longer exists in the repository: the diff is then the
519  // diff against the target. A client should tell the reader to review the
520  // whole change again.
521  bool last_read_lost = 9;
522  // Verdicts are the current verdicts, one per author who gave one, ordered
523  // by the comment that carries them, oldest first.
524  repeated AuthorVerdict verdicts = 10;
525  // Issues are the issues of the same repository that the merge request names,
526  // ascending by number, at most 100. Empty when issues are off.
527  repeated MergeRequestIssue issues = 11;
528  // IssueEvents are the history entries that involve this merge request: the
529  // REFERENCED and RESOLVED events of the issues it names or once named,
530  // oldest first, at most 500. An event can name an issue that is no longer
531  // in issues. Empty when issues are off.
532  repeated IssueEvent issue_events = 12;
533}
534
535// AddCommentRequest describes the comment to add.
536message AddCommentRequest {
537  // Repo is the repository name.
538  string repo = 1;
539  // Number is the merge request number.
540  int64 number = 2;
541  // Path is the file the comment is attached to, as given by the diff of the
542  // merge request: FileDiff.new_path, or old_path for a deleted file. Empty
543  // for a general comment; then line must be 0 and side unspecified.
544  string path = 3;
545  // Line is the 1-based line number on side. It must be the old_number or
546  // new_number of a Line of a hunk of the file; a line outside the hunks is
547  // invalid_argument. 0 for a general comment.
548  int32 line = 4;
549  // Side is the side line counts on. Required when path is set.
550  DiffSide side = 5;
551  // Text is the Markdown source. Required, except when verdict is set.
552  string text = 6;
553  // ReplyTo is the id of the root comment to reply to. Empty for a new root
554  // comment. A reply takes the anchor of its root: path, line, start_line,
555  // side and verdict must then be unset.
556  string reply_to = 7;
557  // StartLine is the 1-based first line of a range ending at line. 0 for a
558  // single line. Needs path; it must be lower than line, and both ends must
559  // be lines of the diff on side.
560  int32 start_line = 8;
561  // Verdict is the judgement to give. Needs the mr:review scope and a root
562  // comment. VERDICT_UNSPECIFIED for a plain comment.
563  Verdict verdict = 9;
564}
565
566// AddCommentResponse holds the new comment.
567message AddCommentResponse {
568  // Comment is the created comment.
569  Comment comment = 1;
570}
571
572// EditCommentRequest describes the new text of a comment.
573message EditCommentRequest {
574  // Repo is the repository name.
575  string repo = 1;
576  // Number is the merge request number.
577  int64 number = 2;
578  // CommentId is the Comment.id to edit.
579  string comment_id = 3;
580  // Text is the new Markdown source. Required, except for a comment that
581  // carries a verdict.
582  string text = 4;
583}
584
585// EditCommentResponse holds the comment after the edit.
586message EditCommentResponse {
587  // Comment is the updated comment.
588  Comment comment = 1;
589}
590
591// DeleteCommentRequest names the comment to delete.
592message DeleteCommentRequest {
593  // Repo is the repository name.
594  string repo = 1;
595  // Number is the merge request number.
596  int64 number = 2;
597  // CommentId is the Comment.id to delete.
598  string comment_id = 3;
599}
600
601// DeleteCommentResponse holds the comment after the deletion.
602message DeleteCommentResponse {
603  // Comment is the deleted comment.
604  Comment comment = 1;
605}
606
607// ResolveCommentRequest changes the resolved state of a comment.
608message ResolveCommentRequest {
609  // Repo is the repository name.
610  string repo = 1;
611  // Number is the merge request number.
612  int64 number = 2;
613  // CommentId is the Comment.id to change.
614  string comment_id = 3;
615  // Resolved is the new state: true to resolve, false to unresolve.
616  bool resolved = 4;
617}
618
619// ResolveCommentResponse holds the comment after the change.
620message ResolveCommentResponse {
621  // Comment is the updated comment.
622  Comment comment = 1;
623}
624
625// CloseMergeRequestRequest names the merge request to close.
626message CloseMergeRequestRequest {
627  // Repo is the repository name.
628  string repo = 1;
629  // Number is the merge request number.
630  int64 number = 2;
631}
632
633// CloseMergeRequestResponse holds the merge request after closing.
634message CloseMergeRequestResponse {
635  // MergeRequest is the closed merge request.
636  MergeRequest merge_request = 1;
637}
638
639// MarkReadyRequest names the draft merge request to mark ready.
640message MarkReadyRequest {
641  // Repo is the repository name.
642  string repo = 1;
643  // Number is the merge request number.
644  int64 number = 2;
645}
646
647// MarkReadyResponse holds the merge request after marking it ready.
648message MarkReadyResponse {
649  // MergeRequest is the merge request with its title stripped of the draft
650  // prefix.
651  MergeRequest merge_request = 1;
652}
653
654// MergeMergeRequestRequest describes the merge to perform.
655message MergeMergeRequestRequest {
656  // Repo is the repository name.
657  string repo = 1;
658  // Number is the merge request number.
659  int64 number = 2;
660  // Mode is how to merge. MERGE_MODE_UNSPECIFIED means fast-forward. The mode
661  // must be in RepoSettings.allowed_merge_modes of the repository.
662  MergeMode mode = 3;
663  // HeadId is the full id of the commit the caller reviewed, that is the
664  // MergeRequest.head_id it was shown. Required. The merge happens only if the
665  // source branch still points to it.
666  string head_id = 4;
667  // DeleteSourceBranch deletes the source branch after the merge. The merge
668  // is refused before anything changes when the source branch is the default
669  // branch of the repository or the source or target of another open merge
670  // request. Servers without the "merge_requests.delete_branch" feature ignore
671  // it.
672  bool delete_source_branch = 5;
673  // IgnoreChecks merges whatever the checks say. Needs the mr:force-merge
674  // scope (permission_denied otherwise). Servers without the
675  // "merge_requests.ignore_checks" feature ignore it: check the feature
676  // before setting it.
677  bool ignore_checks = 6;
678}
679
680// MergeMergeRequestResponse holds the merged merge request.
681message MergeMergeRequestResponse {
682  // MergeRequest is the merge request after the merge: state MERGED,
683  // merged_commit_id set to the new tip of the target branch and merge_mode
684  // set to the mode used.
685  MergeRequest merge_request = 1;
686  // SourceBranchDeleted is true when delete_source_branch was set: the server
687  // deletes the branch after answering. The deletion is skipped, and the
688  // branch kept, if the branch moved or another open merge request uses it
689  // by then; the merge stands either way. Watch reports the deletion with a
690  // Pushed event for the source branch.
691  bool source_branch_deleted = 2;
692}
693
694// EnableAutoMergeRequest describes the auto-merge to enable.
695message EnableAutoMergeRequest {
696  // Repo is the repository name.
697  string repo = 1;
698  // Number is the merge request number.
699  int64 number = 2;
700  // Mode is how to merge. MERGE_MODE_UNSPECIFIED means fast-forward. The mode
701  // must be in RepoSettings.allowed_merge_modes of the repository.
702  MergeMode mode = 3;
703  // HeadId is the full id of the commit the caller reviewed, that is the
704  // MergeRequest.head_id it was shown. Required. The auto-merge is enabled
705  // only if the source branch still points to it; failed_precondition (branch
706  // moved) otherwise.
707  string head_id = 4;
708}
709
710// EnableAutoMergeResponse holds the merge request with auto-merge enabled.
711message EnableAutoMergeResponse {
712  // MergeRequest is the merge request, with auto_merge set.
713  MergeRequest merge_request = 1;
714}
715
716// CancelAutoMergeRequest names the merge request whose auto-merge to cancel.
717message CancelAutoMergeRequest {
718  // Repo is the repository name.
719  string repo = 1;
720  // Number is the merge request number.
721  int64 number = 2;
722}
723
724// CancelAutoMergeResponse holds the merge request after the cancellation.
725message CancelAutoMergeResponse {
726  // MergeRequest is the merge request, with auto_merge unset.
727  MergeRequest merge_request = 1;
728}
729
730// MarkReadRequest records a read position.
731message MarkReadRequest {
732  // Repo is the repository name.
733  string repo = 1;
734  // Number is the merge request number.
735  int64 number = 2;
736  // HeadId is the full id of the commit the caller has reviewed, usually the
737  // MergeRequest.head_id it was shown. Empty means the current head of the
738  // source branch.
739  string head_id = 3;
740}
741
742// MarkReadResponse is empty.
743message MarkReadResponse {}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 18

↑↓ moveenter openesc close