v0.4.0 72f8f2e

git.proto RawHistoryFolder

1// SPDX-License-Identifier: MIT
2
3syntax = "proto3";
4
5package ermite;
6
7import "ermite/types.proto";
8
9// RefKind is the kind of a Git ref.
10enum RefKind {
11  // Not set. In ListRefsRequest.kinds it is rejected; never returned.
12  REF_KIND_UNSPECIFIED = 0;
13  // A branch (refs/heads/*).
14  REF_KIND_BRANCH = 1;
15  // A tag (refs/tags/*), lightweight or annotated.
16  REF_KIND_TAG = 2;
17  // The symbolic ref HEAD, that is the default branch.
18  REF_KIND_HEAD = 3;
19}
20
21// EntryKind is the kind of an entry of a Git tree.
22enum EntryKind {
23  // Not set. Never returned.
24  ENTRY_KIND_UNSPECIFIED = 0;
25  // A regular, non-executable file (mode 100644).
26  ENTRY_KIND_FILE = 1;
27  // An executable file (mode 100755).
28  ENTRY_KIND_EXECUTABLE = 2;
29  // A directory (mode 040000).
30  ENTRY_KIND_DIRECTORY = 3;
31  // A symbolic link (mode 120000). The blob content is the link target.
32  ENTRY_KIND_SYMLINK = 4;
33  // A submodule commit (mode 160000). The id is a commit of another
34  // repository, which this one does not contain.
35  ENTRY_KIND_SUBMODULE = 5;
36}
37
38// FileStatus tells what a commit did to a file.
39enum FileStatus {
40  // Not set. Never returned.
41  FILE_STATUS_UNSPECIFIED = 0;
42  // The file was added.
43  FILE_STATUS_ADDED = 1;
44  // The file was deleted.
45  FILE_STATUS_DELETED = 2;
46  // The content or the mode of the file changed.
47  FILE_STATUS_MODIFIED = 3;
48  // The file was moved, possibly with changes. Rename detection is done by Git.
49  FILE_STATUS_RENAMED = 4;
50  // The file was copied from another file, possibly with changes.
51  FILE_STATUS_COPIED = 5;
52  // The type of the entry changed, for example a file became a symbolic link.
53  FILE_STATUS_TYPE_CHANGED = 6;
54}
55
56// LineKind tells how a line of a hunk relates to the two sides of a diff.
57enum LineKind {
58  // Not set. Never returned.
59  LINE_KIND_UNSPECIFIED = 0;
60  // The line is present, unchanged, on both sides.
61  LINE_KIND_CONTEXT = 1;
62  // The line exists only on the new side.
63  LINE_KIND_ADDITION = 2;
64  // The line exists only on the old side.
65  LINE_KIND_DELETION = 3;
66}
67
68// GitService reads the Git data of repositories. It is read-only: pushes go
69// through Git itself.
70//
71// Every RPC takes the repository name. A repository that does not exist or
72// that the caller cannot read gives not_found. A revision is a branch name, a
73// tag name or a commit id (full, or an unambiguous abbreviation of at least 7
74// characters); empty means HEAD. A revision or path that does not exist gives
75// not_found; so does an empty repository, which has no commit to resolve.
76service GitService {
77  // ListRefs lists the branches, tags and HEAD of a repository. Refs are
78  // ordered by kind (HEAD, branches, tags) then by name.
79  rpc ListRefs(ListRefsRequest) returns (ListRefsResponse);
80  // GetTree lists the entries of a directory at a revision. Fails with
81  // not_found if the path does not exist and invalid_argument if it is not a
82  // directory.
83  rpc GetTree(GetTreeRequest) returns (GetTreeResponse);
84  // ListPaths lists the paths of every file and symbolic link of a revision,
85  // recursively, in Git tree order (the order of `git ls-tree -r`). Directories
86  // and submodules are not listed, nor paths GetBlob cannot address (not valid
87  // UTF-8, or with a control character). Fails with not_found for an unknown
88  // revision or an empty repository. Servers that have it advertise the
89  // feature "git.list_paths" in GetVersion.
90  rpc ListPaths(ListPathsRequest) returns (ListPathsResponse);
91  // GetBlob streams the content of a file at a revision, in chunks of at most
92  // 64 KiB. The first message carries the metadata in info, then the chunks
93  // follow; the memory used by the server does not depend on the file size.
94  // Fails with not_found if the path does not exist and invalid_argument if it
95  // is not a file.
96  rpc GetBlob(GetBlobRequest) returns (stream GetBlobResponse);
97  // ListCommits lists the history reachable from a revision, newest first
98  // (Git's default order), optionally limited to the commits that touched a
99  // path. A page_token that points deeper than 100,000 commits into the
100  // history is invalid_argument.
101  rpc ListCommits(ListCommitsRequest) returns (ListCommitsResponse);
102  // GetCommit returns one commit with its statistics and its diff.
103  rpc GetCommit(GetCommitRequest) returns (GetCommitResponse);
104  // ResolveRevision turns a revision into the id of the commit it designates.
105  rpc ResolveRevision(ResolveRevisionRequest) returns (ResolveRevisionResponse);
106}
107
108// Ref is a branch, a tag or HEAD.
109message Ref {
110  // Name is the full ref name, for example "refs/heads/main" or
111  // "refs/tags/v1.0.0". For HEAD it is "HEAD".
112  string name = 1;
113  // ShortName is the name without its "refs/heads/" or "refs/tags/" prefix. For
114  // HEAD it is the short name of the default branch, or empty if HEAD points
115  // to a branch that does not exist yet.
116  string short_name = 2;
117  // Kind is the kind of the ref.
118  RefKind kind = 3;
119  // Id is the id of the object the ref points to. For an annotated tag it is
120  // the id of the tag object.
121  string id = 4;
122  // CommitId is the id of the commit the ref designates once annotated tags are
123  // followed. It equals id for branches and lightweight tags. It is empty for
124  // a tag that points to something other than a commit.
125  string commit_id = 5;
126}
127
128// ListRefsRequest selects the refs to list.
129message ListRefsRequest {
130  // Repo is the repository name.
131  string repo = 1;
132  // Kinds restricts the result to these kinds. Empty means all kinds.
133  repeated RefKind kinds = 2;
134  // PageSize is the maximum number of refs to return. 0 means the server
135  // default; values above the server maximum are lowered to it.
136  int32 page_size = 3;
137  // PageToken is the next_page_token of a previous response. Empty for the
138  // first page.
139  string page_token = 4;
140}
141
142// ListRefsResponse is one page of refs.
143message ListRefsResponse {
144  // Refs are the refs of this page.
145  repeated Ref refs = 1;
146  // NextPageToken is passed as page_token to get the next page. Empty when
147  // there is no next page.
148  string next_page_token = 2;
149}
150
151// TreeEntry is one entry of a directory.
152message TreeEntry {
153  // Name is the name of the entry in its directory, without slash.
154  string name = 1;
155  // Path is the path of the entry from the repository root, with "/"
156  // separators and no leading slash.
157  string path = 2;
158  // Kind is the kind of the entry.
159  EntryKind kind = 3;
160  // Mode is the Git file mode, for example 0o100644 (33188 in decimal).
161  uint32 mode = 4;
162  // Id is the object id of the blob, tree or submodule commit.
163  string id = 5;
164  // Size is the size in bytes of a file or symbolic link. It is 0 for
165  // directories and submodules.
166  int64 size = 6;
167  // LastCommit is the latest commit that changed the entry. Set only when the
168  // request asked for it with include_last_commit.
169  Commit last_commit = 7;
170}
171
172// GetTreeRequest selects a directory.
173message GetTreeRequest {
174  // Repo is the repository name.
175  string repo = 1;
176  // Revision is a branch, a tag or a commit id. Empty means HEAD.
177  string revision = 2;
178  // Path is the directory, from the repository root, with "/" separators.
179  // Empty means the root.
180  string path = 3;
181  // IncludeLastCommit asks for the last commit of every entry in last_commit.
182  // It costs one history walk, so it is off by default and the server may be
183  // slow on large directories.
184  bool include_last_commit = 4;
185}
186
187// GetTreeResponse lists a directory.
188message GetTreeResponse {
189  // CommitId is the id of the commit the revision resolved to.
190  string commit_id = 1;
191  // TreeId is the object id of the listed directory.
192  string tree_id = 2;
193  // Entries are the entries of the directory: directories first, then the other
194  // entries, each group ordered by name. A response holds at most 5,000
195  // entries (a server limit that may change; rely on truncated, not on the
196  // number): past that, the first 5,000 in this order are returned and
197  // truncated is set. Paging may be added later, additively.
198  repeated TreeEntry entries = 3;
199  // LastCommitsTruncated is true when include_last_commit was set and the
200  // server gave a last_commit to the first entries only (at most 200 of them,
201  // in the order of entries), because each one costs a history lookup. The
202  // other entries have no last_commit although they have one in Git.
203  bool last_commits_truncated = 4;
204  // Truncated is true when the directory has more entries than the response
205  // holds; entries are then the first ones in the documented order.
206  bool truncated = 5;
207}
208
209// ListPathsRequest selects a revision.
210message ListPathsRequest {
211  // Repo is the repository name.
212  string repo = 1;
213  // Revision is a branch, a tag or a commit id. Empty means HEAD.
214  string revision = 2;
215}
216
217// ListPathsResponse lists the file paths of a revision.
218message ListPathsResponse {
219  // CommitId is the id of the commit the revision resolved to.
220  string commit_id = 1;
221  // TreeId is the object id of its root tree.
222  string tree_id = 2;
223  // Paths are the paths of the files and symbolic links, in Git tree order. A
224  // response holds at most 100,000 paths and 8 MiB of path bytes (server limits
225  // that may change; rely on truncated, not on the numbers).
226  repeated string paths = 3;
227  // Truncated is true when more paths exist past the first ones returned.
228  bool truncated = 4;
229}
230
231// BlobInfo describes a file.
232message BlobInfo {
233  // Id is the object id of the blob.
234  string id = 1;
235  // Path is the path of the file from the repository root.
236  string path = 2;
237  // Size is the size of the whole content in bytes.
238  int64 size = 3;
239  // Binary is true if the content is binary, with Git's rule: a NUL byte in the
240  // first 8,000 bytes.
241  bool binary = 4;
242  // MediaType is the detected media type, for example "text/plain" or
243  // "image/png", from the file name and the first bytes. It is
244  // "application/octet-stream" when unknown.
245  string media_type = 5;
246  // Mode is the Git file mode, for example 0o100644 (33188 in decimal).
247  uint32 mode = 6;
248}
249
250// GetBlobRequest selects a file.
251message GetBlobRequest {
252  // Repo is the repository name.
253  string repo = 1;
254  // Revision is a branch, a tag or a commit id. Empty means HEAD.
255  string revision = 2;
256  // Path is the file, from the repository root. It is required.
257  string path = 3;
258}
259
260// GetBlobResponse is one message of the content stream.
261message GetBlobResponse {
262  // Info describes the file. Set in the first message of the stream only.
263  BlobInfo info = 1;
264  // Chunk is the next part of the content, at most 64 KiB, in order. The first
265  // message may have an empty chunk. The chunks of a stream add up to
266  // info.size bytes.
267  bytes chunk = 2;
268}
269
270// ListCommitsRequest selects a page of history.
271message ListCommitsRequest {
272  // Repo is the repository name.
273  string repo = 1;
274  // Revision is where the history starts: a branch, a tag or a commit id.
275  // Empty means HEAD.
276  string revision = 2;
277  // Path restricts the result to the commits that changed this file or
278  // directory. Empty means the whole history.
279  string path = 3;
280  // PageSize is the maximum number of commits to return. 0 means the server
281  // default; values above 100 are lowered to 100.
282  int32 page_size = 4;
283  // PageToken is the next_page_token of a previous response, to continue the
284  // same listing. Empty for the first page. Other fields must be unchanged.
285  string page_token = 5;
286}
287
288// ListCommitsResponse is one page of commits.
289message ListCommitsResponse {
290  // Commits are the commits of this page, newest first.
291  repeated Commit commits = 1;
292  // NextPageToken is passed as page_token to get the next page. Empty when
293  // there is no next page.
294  string next_page_token = 2;
295}
296
297// GetCommitRequest selects a commit.
298message GetCommitRequest {
299  // Repo is the repository name.
300  string repo = 1;
301  // Revision is a branch, a tag or a commit id. Empty means HEAD.
302  string revision = 2;
303}
304
305// GetCommitResponse holds a commit, its statistics and its diff.
306message GetCommitResponse {
307  // Commit is the commit metadata.
308  Commit commit = 1;
309  // Stats are the totals over all the changed files, including files that the
310  // diff omits or truncates.
311  DiffStats stats = 2;
312  // Diff is the structured diff against the first parent, or against the empty
313  // tree for a root commit. For a merge commit this is the change relative to
314  // the first parent.
315  Diff diff = 3;
316}
317
318// DiffStats are the totals of a diff.
319message DiffStats {
320  // FilesChanged is the number of changed files.
321  int32 files_changed = 1;
322  // Additions is the number of added lines. Binary files count for 0.
323  int32 additions = 2;
324  // Deletions is the number of deleted lines. Binary files count for 0.
325  int32 deletions = 3;
326}
327
328// Diff is the structured difference introduced by a commit.
329//
330// The server limits its size: at most 300 files, at most 2,000 lines in one
331// file and at most 20,000 lines in total (hunk lines, context included). These
332// numbers are server behaviour and may change; clients must rely on the
333// truncated flags, not on the numbers.
334message Diff {
335  // Files are the changed files, ordered by path. Files past the file limit are
336  // omitted.
337  repeated FileDiff files = 1;
338  // Truncated is true when the diff is incomplete: files were omitted, or at
339  // least one listed file has truncated set. DiffStats still count everything.
340  bool truncated = 2;
341}
342
343// FileDiff is the change of one file.
344message FileDiff {
345  // OldPath is the path before the commit. Empty for an added file.
346  string old_path = 1;
347  // NewPath is the path after the commit. Empty for a deleted file.
348  string new_path = 2;
349  // Status tells what happened to the file.
350  FileStatus status = 3;
351  // OldMode is the Git file mode before the commit, or 0 for an added file.
352  uint32 old_mode = 4;
353  // NewMode is the Git file mode after the commit, or 0 for a deleted file.
354  uint32 new_mode = 5;
355  // OldId is the blob id before the commit. Empty for an added file.
356  string old_id = 6;
357  // NewId is the blob id after the commit. Empty for a deleted file.
358  string new_id = 7;
359  // Binary is true if Git treats the file as binary (numstat reports "-"). A
360  // binary file has no hunks and additions and deletions are 0.
361  bool binary = 8;
362  // Additions is the number of added lines.
363  int32 additions = 9;
364  // Deletions is the number of deleted lines.
365  int32 deletions = 10;
366  // Similarity is the percentage (0-100) of unchanged content for a renamed or
367  // copied file, and 0 otherwise.
368  int32 similarity = 11;
369  // Truncated is true when the file exceeded a diff limit: hunks is then empty
370  // although the file changed. Additions and deletions remain accurate.
371  bool truncated = 12;
372  // Hunks are the changed regions, in file order. Empty for a binary file, a
373  // truncated file, a pure rename and a mode-only change.
374  repeated Hunk hunks = 13;
375}
376
377// Hunk is a contiguous changed region with its context.
378message Hunk {
379  // OldStart is the 1-based first line of the region in the old file. 0 when
380  // old_lines is 0 and the file was added.
381  int32 old_start = 1;
382  // OldLines is the number of old-side lines in the hunk.
383  int32 old_lines = 2;
384  // NewStart is the 1-based first line of the region in the new file. 0 when
385  // new_lines is 0 and the file was deleted.
386  int32 new_start = 3;
387  // NewLines is the number of new-side lines in the hunk.
388  int32 new_lines = 4;
389  // Header is the text after the second "@@" of the hunk header, usually the
390  // enclosing function. It may be empty.
391  string header = 5;
392  // Lines are the lines of the hunk, in order.
393  repeated Line lines = 6;
394}
395
396// Line is one line of a hunk.
397message Line {
398  // Kind tells which side the line belongs to.
399  LineKind kind = 1;
400  // OldNumber is the 1-based line number on the old side. 0 for an addition.
401  int32 old_number = 2;
402  // NewNumber is the 1-based line number on the new side. 0 for a deletion.
403  int32 new_number = 3;
404  // Text is the content without the line terminator. Bytes that are not valid
405  // UTF-8 are replaced by the replacement character.
406  string text = 4;
407  // NoNewlineAtEof is true when this is the last line of its side and the file
408  // does not end with a line break there.
409  bool no_newline_at_eof = 5;
410}
411
412// ResolveRevisionRequest names a revision.
413message ResolveRevisionRequest {
414  // Repo is the repository name.
415  string repo = 1;
416  // Revision is a branch, a tag or a commit id. Empty means HEAD.
417  string revision = 2;
418}
419
420// ResolveRevisionResponse holds the resolved commit.
421message ResolveRevisionResponse {
422  // CommitId is the full id of the commit the revision designates, after
423  // following annotated tags.
424  string commit_id = 1;
425  // Ref is the full name of the ref the revision matched, for example
426  // "refs/heads/main". Empty when the revision was a commit id or for HEAD
427  // when it is resolved by default.
428  string ref = 2;
429}

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