detached dca0ed7

feat(api): report truncated trees and last commits in GetTree

commit
dca0ed73accf04bafe05087d9c54b8a58e7a55b1
author
brice · · 2026-10-10 10:20 UTC
parent
a137f54
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +43 -5
M gen/ermite/git.pb.go +31 -4
@@ -678,8 +678,19 @@ type GetTreeResponse struct {
678678 // TreeId is the object id of the listed directory.
679679 TreeId string `protobuf:"bytes,2,opt,name=tree_id,json=treeId,proto3" json:"tree_id,omitempty"`
680680 // Entries are the entries of the directory: directories first, then the other
681- // entries, each group ordered by name.
682- Entries []*TreeEntry `protobuf:"bytes,3,rep,name=entries,proto3" json:"entries,omitempty"`
681+ // entries, each group ordered by name. A response holds at most 5,000
682+ // entries (a server limit that may change; rely on truncated, not on the
683+ // number): past that, the first 5,000 in this order are returned and
684+ // truncated is set. Paging may be added later, additively.
685+ Entries []*TreeEntry `protobuf:"bytes,3,rep,name=entries,proto3" json:"entries,omitempty"`
686+ // LastCommitsTruncated is true when include_last_commit was set and the
687+ // server gave a last_commit to the first entries only (at most 200 of them,
688+ // in the order of entries), because each one costs a history lookup. The
689+ // other entries have no last_commit although they have one in Git.
690+ LastCommitsTruncated bool `protobuf:"varint,4,opt,name=last_commits_truncated,json=lastCommitsTruncated,proto3" json:"last_commits_truncated,omitempty"`
691+ // Truncated is true when the directory has more entries than the response
692+ // holds; entries are then the first ones in the documented order.
693+ Truncated bool `protobuf:"varint,5,opt,name=truncated,proto3" json:"truncated,omitempty"`
683694 unknownFields protoimpl.UnknownFields
684695 sizeCache protoimpl.SizeCache
685696 }
@@ -735,6 +746,20 @@ func (x *GetTreeResponse) GetEntries() []*TreeEntry {
735746 return nil
736747 }
737748
749+func (x *GetTreeResponse) GetLastCommitsTruncated() bool {
750+ if x != nil {
751+ return x.LastCommitsTruncated
752+ }
753+ return false
754+}
755+
756+func (x *GetTreeResponse) GetTruncated() bool {
757+ if x != nil {
758+ return x.Truncated
759+ }
760+ return false
761+}
762+
738763 // BlobInfo describes a file.
739764 type BlobInfo struct {
740765 state protoimpl.MessageState `protogen:"open.v1"`
@@ -1823,11 +1848,13 @@ const file_ermite_git_proto_rawDesc = "" +
18231848 "\x04repo\x18\x01 \x01(\tR\x04repo\x12\x1a\n" +
18241849 "\brevision\x18\x02 \x01(\tR\brevision\x12\x12\n" +
18251850 "\x04path\x18\x03 \x01(\tR\x04path\x12.\n" +
1826- "\x13include_last_commit\x18\x04 \x01(\bR\x11includeLastCommit\"t\n" +
1851+ "\x13include_last_commit\x18\x04 \x01(\bR\x11includeLastCommit\"\xc8\x01\n" +
18271852 "\x0fGetTreeResponse\x12\x1b\n" +
18281853 "\tcommit_id\x18\x01 \x01(\tR\bcommitId\x12\x17\n" +
18291854 "\atree_id\x18\x02 \x01(\tR\x06treeId\x12+\n" +
1830- "\aentries\x18\x03 \x03(\v2\x11.ermite.TreeEntryR\aentries\"\x8d\x01\n" +
1855+ "\aentries\x18\x03 \x03(\v2\x11.ermite.TreeEntryR\aentries\x124\n" +
1856+ "\x16last_commits_truncated\x18\x04 \x01(\bR\x14lastCommitsTruncated\x12\x1c\n" +
1857+ "\ttruncated\x18\x05 \x01(\bR\ttruncated\"\x8d\x01\n" +
18311858 "\bBlobInfo\x12\x0e\n" +
18321859 "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" +
18331860 "\x04path\x18\x02 \x01(\tR\x04path\x12\x12\n" +
@@ -678,8 +678,19 @@ type GetTreeResponse struct {
678 // TreeId is the object id of the listed directory.678 // TreeId is the object id of the listed directory.
679 TreeId string `protobuf:"bytes,2,opt,name=tree_id,json=treeId,proto3" json:"tree_id,omitempty"`679 TreeId string `protobuf:"bytes,2,opt,name=tree_id,json=treeId,proto3" json:"tree_id,omitempty"`
680 // Entries are the entries of the directory: directories first, then the other680 // Entries are the entries of the directory: directories first, then the other
681- // entries, each group ordered by name.681+ // entries, each group ordered by name. A response holds at most 5,000
682- Entries []*TreeEntry `protobuf:"bytes,3,rep,name=entries,proto3" json:"entries,omitempty"`682+ // entries (a server limit that may change; rely on truncated, not on the
683+ // number): past that, the first 5,000 in this order are returned and
684+ // truncated is set. Paging may be added later, additively.
685+ Entries []*TreeEntry `protobuf:"bytes,3,rep,name=entries,proto3" json:"entries,omitempty"`
686+ // LastCommitsTruncated is true when include_last_commit was set and the
687+ // server gave a last_commit to the first entries only (at most 200 of them,
688+ // in the order of entries), because each one costs a history lookup. The
689+ // other entries have no last_commit although they have one in Git.
690+ LastCommitsTruncated bool `protobuf:"varint,4,opt,name=last_commits_truncated,json=lastCommitsTruncated,proto3" json:"last_commits_truncated,omitempty"`
691+ // Truncated is true when the directory has more entries than the response
692+ // holds; entries are then the first ones in the documented order.
693+ Truncated bool `protobuf:"varint,5,opt,name=truncated,proto3" json:"truncated,omitempty"`
683 unknownFields protoimpl.UnknownFields694 unknownFields protoimpl.UnknownFields
684 sizeCache protoimpl.SizeCache695 sizeCache protoimpl.SizeCache
685 }696 }
@@ -735,6 +746,20 @@ func (x *GetTreeResponse) GetEntries() []*TreeEntry {
735 return nil746 return nil
736 }747 }
737 748
749+func (x *GetTreeResponse) GetLastCommitsTruncated() bool {
750+ if x != nil {
751+ return x.LastCommitsTruncated
752+ }
753+ return false
754+}
755+
756+func (x *GetTreeResponse) GetTruncated() bool {
757+ if x != nil {
758+ return x.Truncated
759+ }
760+ return false
761+}
762+
738 // BlobInfo describes a file.763 // BlobInfo describes a file.
739 type BlobInfo struct {764 type BlobInfo struct {
740 state protoimpl.MessageState `protogen:"open.v1"`765 state protoimpl.MessageState `protogen:"open.v1"`
@@ -1823,11 +1848,13 @@ const file_ermite_git_proto_rawDesc = "" +
1823 "\x04repo\x18\x01 \x01(\tR\x04repo\x12\x1a\n" +1848 "\x04repo\x18\x01 \x01(\tR\x04repo\x12\x1a\n" +
1824 "\brevision\x18\x02 \x01(\tR\brevision\x12\x12\n" +1849 "\brevision\x18\x02 \x01(\tR\brevision\x12\x12\n" +
1825 "\x04path\x18\x03 \x01(\tR\x04path\x12.\n" +1850 "\x04path\x18\x03 \x01(\tR\x04path\x12.\n" +
1826- "\x13include_last_commit\x18\x04 \x01(\bR\x11includeLastCommit\"t\n" +1851+ "\x13include_last_commit\x18\x04 \x01(\bR\x11includeLastCommit\"\xc8\x01\n" +
1827 "\x0fGetTreeResponse\x12\x1b\n" +1852 "\x0fGetTreeResponse\x12\x1b\n" +
1828 "\tcommit_id\x18\x01 \x01(\tR\bcommitId\x12\x17\n" +1853 "\tcommit_id\x18\x01 \x01(\tR\bcommitId\x12\x17\n" +
1829 "\atree_id\x18\x02 \x01(\tR\x06treeId\x12+\n" +1854 "\atree_id\x18\x02 \x01(\tR\x06treeId\x12+\n" +
1830- "\aentries\x18\x03 \x03(\v2\x11.ermite.TreeEntryR\aentries\"\x8d\x01\n" +1855+ "\aentries\x18\x03 \x03(\v2\x11.ermite.TreeEntryR\aentries\x124\n" +
1856+ "\x16last_commits_truncated\x18\x04 \x01(\bR\x14lastCommitsTruncated\x12\x1c\n" +
1857+ "\ttruncated\x18\x05 \x01(\bR\ttruncated\"\x8d\x01\n" +
1831 "\bBlobInfo\x12\x0e\n" +1858 "\bBlobInfo\x12\x0e\n" +
1832 "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" +1859 "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" +
1833 "\x04path\x18\x02 \x01(\tR\x04path\x12\x12\n" +1860 "\x04path\x18\x02 \x01(\tR\x04path\x12\x12\n" +
M proto/ermite/git.proto +12 -1
@@ -183,8 +183,19 @@ message GetTreeResponse {
183183 // TreeId is the object id of the listed directory.
184184 string tree_id = 2;
185185 // Entries are the entries of the directory: directories first, then the other
186- // entries, each group ordered by name.
186+ // entries, each group ordered by name. A response holds at most 5,000
187+ // entries (a server limit that may change; rely on truncated, not on the
188+ // number): past that, the first 5,000 in this order are returned and
189+ // truncated is set. Paging may be added later, additively.
187190 repeated TreeEntry entries = 3;
191+ // LastCommitsTruncated is true when include_last_commit was set and the
192+ // server gave a last_commit to the first entries only (at most 200 of them,
193+ // in the order of entries), because each one costs a history lookup. The
194+ // other entries have no last_commit although they have one in Git.
195+ bool last_commits_truncated = 4;
196+ // Truncated is true when the directory has more entries than the response
197+ // holds; entries are then the first ones in the documented order.
198+ bool truncated = 5;
188199 }
189200
190201 // BlobInfo describes a file.
@@ -183,8 +183,19 @@ message GetTreeResponse {
183 // TreeId is the object id of the listed directory.183 // TreeId is the object id of the listed directory.
184 string tree_id = 2;184 string tree_id = 2;
185 // Entries are the entries of the directory: directories first, then the other185 // Entries are the entries of the directory: directories first, then the other
186- // entries, each group ordered by name.186+ // entries, each group ordered by name. A response holds at most 5,000
187+ // entries (a server limit that may change; rely on truncated, not on the
188+ // number): past that, the first 5,000 in this order are returned and
189+ // truncated is set. Paging may be added later, additively.
187 repeated TreeEntry entries = 3;190 repeated TreeEntry entries = 3;
191+ // LastCommitsTruncated is true when include_last_commit was set and the
192+ // server gave a last_commit to the first entries only (at most 200 of them,
193+ // in the order of entries), because each one costs a history lookup. The
194+ // other entries have no last_commit although they have one in Git.
195+ bool last_commits_truncated = 4;
196+ // Truncated is true when the directory has more entries than the response
197+ // holds; entries are then the first ones in the documented order.
198+ bool truncated = 5;
188 }199 }
189 200
190 // BlobInfo describes a file.201 // BlobInfo describes a file.

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