v0.7.0 d244a03

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// MergeRequest asks to merge one branch of a repository into another branch
37// of the same repository. It is about a branch, not about who wrote it.
38message MergeRequest {
39  // Repo is the name of the repository.
40  string repo = 1;
41  // Number identifies the merge request within its repository, starting at 1
42  // and never reused. It is written "!<number>" in messages and URLs.
43  int64 number = 2;
44  // Title is a one-line plain-text title, at most 120 characters.
45  string title = 3;
46  // Description is a plain-text description, at most 8,000 characters. It may
47  // be empty. Clients show it escaped, with line breaks kept.
48  string description = 4;
49  // SourceBranch is the short name of the branch to merge, for example
50  // "feat/x".
51  string source_branch = 5;
52  // TargetBranch is the short name of the branch to merge into, for example
53  // "main".
54  string target_branch = 6;
55  // State is where the merge request is in its life.
56  MergeRequestState state = 7;
57  // Author names who created the merge request: the label of the token that
58  // was used, "root" for the root token, or "owner" for a web session. It is
59  // informational: labels are not unique and the token may be gone.
60  string author = 8;
61  // CreatedAt is when the merge request was created.
62  google.protobuf.Timestamp created_at = 9;
63  // UpdatedAt is when the merge request last changed: title, description,
64  // state, or a comment added or resolved. Pushes to the source branch do not
65  // change it.
66  google.protobuf.Timestamp updated_at = 10;
67  // HeadId is the id of the commit the source branch points to. While the
68  // merge request is open it is read from Git at every call, so it changes
69  // when the branch is pushed; it is empty if the branch was deleted. Once
70  // merged or closed it is the head at that moment.
71  string head_id = 11;
72  // MergedCommitId is the id of the commit the target branch points to after
73  // the merge: the head for a fast-forward, the new commit for a squash.
74  // Empty unless state is MERGED.
75  string merged_commit_id = 12;
76  // MergeMode is how the merge request was merged. MERGE_MODE_UNSPECIFIED
77  // unless state is MERGED.
78  MergeMode merge_mode = 13;
79}
80
81// Comment is a note on a merge request, either general or attached to a line
82// of its diff.
83message Comment {
84  // Id identifies the comment within its merge request. Opaque.
85  string id = 1;
86  // Author names who wrote the comment, like MergeRequest.author.
87  string author = 2;
88  // Path is the path of the commented file in the diff (the new path, or the
89  // old path of a deleted file). Empty for a general comment.
90  string path = 3;
91  // Line is the 1-based line number on side. 0 for a general comment.
92  int32 line = 4;
93  // Side tells whether line counts on the old or the new side of the diff.
94  // DIFF_SIDE_UNSPECIFIED for a general comment.
95  DiffSide side = 5;
96  // CommitId is the head of the merge request when the comment was written.
97  // When it differs from the current head the line may have moved; clients
98  // may show the comment as outdated.
99  string commit_id = 6;
100  // Text is the plain-text content, at most 8,000 characters. Clients show it
101  // escaped, with line breaks kept.
102  string text = 7;
103  // Resolved is true once the comment was marked resolved.
104  bool resolved = 8;
105  // CreatedAt is when the comment was written.
106  google.protobuf.Timestamp created_at = 9;
107}
108
109// MergeRequestService reviews and merges branches.
110//
111// Every RPC takes the repository name and, except for creation and listing,
112// the merge request number. A repository that does not exist or that the
113// caller cannot read gives not_found; so does an unknown number. Reading
114// (ListMergeRequests, GetMergeRequest) needs the same access as reading the
115// repository: nothing for a public one, the repo:read scope for a private
116// one. Writing needs a scope on the repository, given per RPC; a caller
117// without it gets permission_denied.
118//
119// Text fields follow the same rules everywhere: valid UTF-8, no control
120// characters (except the line break in description and comment text) and no
121// Unicode bidirectional override or isolate characters; title is one line of
122// at most 120 characters, description and comment text at most 8,000
123// characters. A request that breaks a rule is rejected whole with
124// invalid_argument, and the error carries a BadRequest detail naming the
125// fields.
126//
127// Servers that implement this service list "merge_requests" in
128// GetVersionResponse.features.
129service MergeRequestService {
130  // CreateMergeRequest opens a merge request. Needs the mr:write scope. Fails
131  // with invalid_argument if a text rule is broken, if a branch does not exist
132  // or if source and target are the same branch, and with already_exists if an
133  // open merge request already has the same source and target.
134  rpc CreateMergeRequest(CreateMergeRequestRequest) returns (CreateMergeRequestResponse);
135  // ListMergeRequests lists the merge requests of a repository, highest
136  // number (newest) first, optionally restricted to one state. The listed
137  // merge requests carry no diff or comments; head_id is set. Fails with
138  // not_found if the repository does not exist or is not readable.
139  rpc ListMergeRequests(ListMergeRequestsRequest) returns (ListMergeRequestsResponse);
140  // GetMergeRequest returns one merge request with its commits, its diff and
141  // its comments. The diff compares the target with the head (what the merge
142  // would bring: "target...head"), or, with since_last_read, the head the
143  // caller last marked read with the current head. Fails with not_found if
144  // the repository or the number is unknown.
145  rpc GetMergeRequest(GetMergeRequestRequest) returns (GetMergeRequestResponse);
146  // AddComment adds a general comment or a comment on a line of the diff.
147  // Needs the mr:write scope. Fails with invalid_argument if the text breaks
148  // a rule or if path, line and side do not designate a line of the current
149  // diff of the merge request, and with failed_precondition if the merge
150  // request is not open.
151  rpc AddComment(AddCommentRequest) returns (AddCommentResponse);
152  // ResolveComment marks a comment resolved or unresolved. Needs the mr:write
153  // scope. Fails with not_found if the comment is unknown and with
154  // failed_precondition if the merge request is not open. Setting the state
155  // the comment already has succeeds and changes nothing.
156  rpc ResolveComment(ResolveCommentRequest) returns (ResolveCommentResponse);
157  // CloseMergeRequest closes an open merge request without merging it. Needs
158  // the mr:write scope. Fails with failed_precondition if the merge request
159  // is not open. A closed merge request cannot be reopened: open a new one.
160  rpc CloseMergeRequest(CloseMergeRequestRequest) returns (CloseMergeRequestResponse);
161  // MergeMergeRequest merges an open merge request. Needs the mr:merge scope.
162  // The caller passes the head it reviewed: the server merges only if the
163  // source branch still points to it, so a push between review and merge is
164  // never merged unseen. Fails with invalid_argument if head_id is empty or
165  // not a commit id, and with failed_precondition if the merge request is not
166  // open, if the source branch no longer points to head_id ("branch moved,
167  // read again"), if the target is not an ancestor of the head (rebase and
168  // push again), if the mode is not allowed by RepoSettings, or if a check
169  // fails and RepoSettings.failing_checks_block is set. Merges of one
170  // repository run one at a time. Repeating a call that succeeded fails with
171  // failed_precondition (not open). On success the server publishes
172  // MergeRequestMerged then Pushed for the target branch.
173  rpc MergeMergeRequest(MergeMergeRequestRequest) returns (MergeMergeRequestResponse);
174  // MarkRead records the head the caller has reviewed, for the since_last_read
175  // option of GetMergeRequest. There is one read position per merge request,
176  // the reviewer's. Needs the mr:write scope. Marking a commit that does not
177  // exist in the repository is invalid_argument.
178  rpc MarkRead(MarkReadRequest) returns (MarkReadResponse);
179}
180
181// CreateMergeRequestRequest describes the merge request to open.
182message CreateMergeRequestRequest {
183  // Repo is the repository name.
184  string repo = 1;
185  // Title is the one-line title. Required.
186  string title = 2;
187  // Description is the optional description.
188  string description = 3;
189  // SourceBranch is the short name of the branch to merge. Required; the
190  // branch must exist.
191  string source_branch = 4;
192  // TargetBranch is the short name of the branch to merge into. Empty means
193  // the default branch of the repository. The branch must exist and differ
194  // from source_branch.
195  string target_branch = 5;
196}
197
198// CreateMergeRequestResponse holds the new merge request.
199message CreateMergeRequestResponse {
200  // MergeRequest is the created merge request.
201  MergeRequest merge_request = 1;
202}
203
204// ListMergeRequestsRequest selects a page of merge requests.
205message ListMergeRequestsRequest {
206  // Repo is the repository name.
207  string repo = 1;
208  // State restricts the result to one state. MERGE_REQUEST_STATE_UNSPECIFIED
209  // means every state.
210  MergeRequestState state = 2;
211  // PageSize is the maximum number of merge requests to return. 0 means the
212  // server default; values above the server maximum are lowered to it.
213  int32 page_size = 3;
214  // PageToken is the next_page_token of a previous response, to continue the
215  // same listing. Empty for the first page. Other fields must be unchanged.
216  string page_token = 4;
217}
218
219// ListMergeRequestsResponse is one page of merge requests.
220message ListMergeRequestsResponse {
221  // MergeRequests are the merge requests of this page, highest number first.
222  repeated MergeRequest merge_requests = 1;
223  // NextPageToken is passed as page_token to get the next page. Empty when
224  // there is no next page.
225  string next_page_token = 2;
226}
227
228// GetMergeRequestRequest selects a merge request.
229message GetMergeRequestRequest {
230  // Repo is the repository name.
231  string repo = 1;
232  // Number is the merge request number.
233  int64 number = 2;
234  // SinceLastRead asks for the diff between the head recorded by MarkRead and
235  // the current head instead of the diff against the target. It works after a
236  // force-push as long as the recorded commit still exists in the repository.
237  // When nothing was marked read, or the recorded commit is gone, the response
238  // holds the diff against the target and says so in last_read_id and
239  // last_read_lost.
240  bool since_last_read = 3;
241}
242
243// GetMergeRequestResponse holds a merge request with its review data.
244message GetMergeRequestResponse {
245  // MergeRequest is the merge request.
246  MergeRequest merge_request = 1;
247  // Commits are the commits of the head that are not in the target
248  // ("target..head"), newest first. At most 100 are returned (a server limit
249  // that may change; rely on commits_truncated, not on the number). Empty when
250  // the source branch was deleted.
251  repeated Commit commits = 2;
252  // CommitsTruncated is true when the branch has more commits than commits
253  // holds.
254  bool commits_truncated = 3;
255  // DiffBaseId is the id of the commit the diff compares from: the merge base
256  // of the target and the head, or the last read head when since_last_read
257  // applied. Empty when the source branch was deleted; diff is then empty.
258  string diff_base_id = 4;
259  // Stats are the totals of the diff, including files that it omits or
260  // truncates.
261  DiffStats stats = 5;
262  // Diff is the structured diff from diff_base_id to the head, with the same
263  // limits and truncated flags as GetCommitResponse.diff.
264  Diff diff = 6;
265  // Comments are every comment of the merge request, oldest first.
266  repeated Comment comments = 7;
267  // LastReadId is the head recorded by MarkRead, whether or not
268  // since_last_read was set. Empty when nothing was marked read.
269  string last_read_id = 8;
270  // LastReadLost is true when since_last_read was set, a head was recorded,
271  // but that commit no longer exists in the repository: the diff is then the
272  // diff against the target. A client should tell the reader to review the
273  // whole change again.
274  bool last_read_lost = 9;
275}
276
277// AddCommentRequest describes the comment to add.
278message AddCommentRequest {
279  // Repo is the repository name.
280  string repo = 1;
281  // Number is the merge request number.
282  int64 number = 2;
283  // Path is the file the comment is attached to, as given by the diff of the
284  // merge request: FileDiff.new_path, or old_path for a deleted file. Empty
285  // for a general comment; then line must be 0 and side unspecified.
286  string path = 3;
287  // Line is the 1-based line number on side. It must be the old_number or
288  // new_number of a Line of a hunk of the file; a line outside the hunks is
289  // invalid_argument. 0 for a general comment.
290  int32 line = 4;
291  // Side is the side line counts on. Required when path is set.
292  DiffSide side = 5;
293  // Text is the plain-text content. Required.
294  string text = 6;
295}
296
297// AddCommentResponse holds the new comment.
298message AddCommentResponse {
299  // Comment is the created comment.
300  Comment comment = 1;
301}
302
303// ResolveCommentRequest changes the resolved state of a comment.
304message ResolveCommentRequest {
305  // Repo is the repository name.
306  string repo = 1;
307  // Number is the merge request number.
308  int64 number = 2;
309  // CommentId is the Comment.id to change.
310  string comment_id = 3;
311  // Resolved is the new state: true to resolve, false to unresolve.
312  bool resolved = 4;
313}
314
315// ResolveCommentResponse holds the comment after the change.
316message ResolveCommentResponse {
317  // Comment is the updated comment.
318  Comment comment = 1;
319}
320
321// CloseMergeRequestRequest names the merge request to close.
322message CloseMergeRequestRequest {
323  // Repo is the repository name.
324  string repo = 1;
325  // Number is the merge request number.
326  int64 number = 2;
327}
328
329// CloseMergeRequestResponse holds the merge request after closing.
330message CloseMergeRequestResponse {
331  // MergeRequest is the closed merge request.
332  MergeRequest merge_request = 1;
333}
334
335// MergeMergeRequestRequest describes the merge to perform.
336message MergeMergeRequestRequest {
337  // Repo is the repository name.
338  string repo = 1;
339  // Number is the merge request number.
340  int64 number = 2;
341  // Mode is how to merge. MERGE_MODE_UNSPECIFIED means fast-forward. The mode
342  // must be in RepoSettings.allowed_merge_modes of the repository.
343  MergeMode mode = 3;
344  // HeadId is the full id of the commit the caller reviewed, that is the
345  // MergeRequest.head_id it was shown. Required. The merge happens only if the
346  // source branch still points to it.
347  string head_id = 4;
348  // DeleteSourceBranch deletes the source branch after the merge. The merge
349  // is refused before anything changes when the source branch is the default
350  // branch of the repository or the source or target of another open merge
351  // request. Servers without the "merge_requests.delete_branch" feature ignore
352  // it.
353  bool delete_source_branch = 5;
354}
355
356// MergeMergeRequestResponse holds the merged merge request.
357message MergeMergeRequestResponse {
358  // MergeRequest is the merge request after the merge: state MERGED,
359  // merged_commit_id set to the new tip of the target branch and merge_mode
360  // set to the mode used.
361  MergeRequest merge_request = 1;
362  // SourceBranchDeleted is true when delete_source_branch was set and the
363  // branch is gone. It is false when the deletion failed after the merge (the
364  // branch moved in between, say): the merge stands and the branch is kept.
365  bool source_branch_deleted = 2;
366}
367
368// MarkReadRequest records a read position.
369message MarkReadRequest {
370  // Repo is the repository name.
371  string repo = 1;
372  // Number is the merge request number.
373  int64 number = 2;
374  // HeadId is the full id of the commit the caller has reviewed, usually the
375  // MergeRequest.head_id it was shown. Empty means the current head of the
376  // source branch.
377  string head_id = 3;
378}
379
380// MarkReadResponse is empty.
381message 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