···99import (
1010 protoreflect "google.golang.org/protobuf/reflect/protoreflect"
1111 protoimpl "google.golang.org/protobuf/runtime/protoimpl"
1212+ timestamppb "google.golang.org/protobuf/types/known/timestamppb"
1213 reflect "reflect"
1314 sync "sync"
1415 unsafe "unsafe"
···7576 return ""
7677}
77787979+type CommitLogRequest struct {
8080+ state protoimpl.MessageState `protogen:"open.v1"`
8181+ // repo DID
8282+ Repo string `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"`
8383+ // Ranges to include in the git log (revspec, "A..B", "A...B", etc.).
8484+ // At least one range, or all_refs must be specified.
8585+ Ranges [][]byte `protobuf:"bytes,2,rep,name=ranges,proto3" json:"ranges,omitempty"`
8686+ // If true, all refs are searched for commits.
8787+ // Must not be true when ranges are given.
8888+ AllRefs bool `protobuf:"varint,3,opt,name=all_refs,json=allRefs,proto3" json:"all_refs,omitempty"`
8989+ // After is an optional parameter to specify the earliest commit to consider.
9090+ After *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=after,proto3" json:"after,omitempty"`
9191+ // Before is an optional parameter to specify the latest commit to consider.
9292+ Before *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=before,proto3" json:"before,omitempty"`
9393+ // MaxCommits is an optional parameter to specify the maximum number of commits
9494+ // to return. If max_commits is 0, all commits that match the criteria will be
9595+ // returned.
9696+ MaxCommits uint32 `protobuf:"varint,6,opt,name=max_commits,json=maxCommits,proto3" json:"max_commits,omitempty"`
9797+ // Skip is an optional parameter to specify the number of commits to skip.
9898+ // This can be used to implement a poor mans pagination.
9999+ Skip uint32 `protobuf:"varint,7,opt,name=skip,proto3" json:"skip,omitempty"`
100100+ unknownFields protoimpl.UnknownFields
101101+ sizeCache protoimpl.SizeCache
102102+}
103103+104104+func (x *CommitLogRequest) Reset() {
105105+ *x = CommitLogRequest{}
106106+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[1]
107107+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
108108+ ms.StoreMessageInfo(mi)
109109+}
110110+111111+func (x *CommitLogRequest) String() string {
112112+ return protoimpl.X.MessageStringOf(x)
113113+}
114114+115115+func (*CommitLogRequest) ProtoMessage() {}
116116+117117+func (x *CommitLogRequest) ProtoReflect() protoreflect.Message {
118118+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[1]
119119+ if x != nil {
120120+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
121121+ if ms.LoadMessageInfo() == nil {
122122+ ms.StoreMessageInfo(mi)
123123+ }
124124+ return ms
125125+ }
126126+ return mi.MessageOf(x)
127127+}
128128+129129+// Deprecated: Use CommitLogRequest.ProtoReflect.Descriptor instead.
130130+func (*CommitLogRequest) Descriptor() ([]byte, []int) {
131131+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{1}
132132+}
133133+134134+func (x *CommitLogRequest) GetRepo() string {
135135+ if x != nil {
136136+ return x.Repo
137137+ }
138138+ return ""
139139+}
140140+141141+func (x *CommitLogRequest) GetRanges() [][]byte {
142142+ if x != nil {
143143+ return x.Ranges
144144+ }
145145+ return nil
146146+}
147147+148148+func (x *CommitLogRequest) GetAllRefs() bool {
149149+ if x != nil {
150150+ return x.AllRefs
151151+ }
152152+ return false
153153+}
154154+155155+func (x *CommitLogRequest) GetAfter() *timestamppb.Timestamp {
156156+ if x != nil {
157157+ return x.After
158158+ }
159159+ return nil
160160+}
161161+162162+func (x *CommitLogRequest) GetBefore() *timestamppb.Timestamp {
163163+ if x != nil {
164164+ return x.Before
165165+ }
166166+ return nil
167167+}
168168+169169+func (x *CommitLogRequest) GetMaxCommits() uint32 {
170170+ if x != nil {
171171+ return x.MaxCommits
172172+ }
173173+ return 0
174174+}
175175+176176+func (x *CommitLogRequest) GetSkip() uint32 {
177177+ if x != nil {
178178+ return x.Skip
179179+ }
180180+ return 0
181181+}
182182+183183+type CommitLogResponse struct {
184184+ state protoimpl.MessageState `protogen:"open.v1"`
185185+ Commits []*GitCommit `protobuf:"bytes,1,rep,name=commits,proto3" json:"commits,omitempty"`
186186+ unknownFields protoimpl.UnknownFields
187187+ sizeCache protoimpl.SizeCache
188188+}
189189+190190+func (x *CommitLogResponse) Reset() {
191191+ *x = CommitLogResponse{}
192192+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[2]
193193+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
194194+ ms.StoreMessageInfo(mi)
195195+}
196196+197197+func (x *CommitLogResponse) String() string {
198198+ return protoimpl.X.MessageStringOf(x)
199199+}
200200+201201+func (*CommitLogResponse) ProtoMessage() {}
202202+203203+func (x *CommitLogResponse) ProtoReflect() protoreflect.Message {
204204+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[2]
205205+ if x != nil {
206206+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
207207+ if ms.LoadMessageInfo() == nil {
208208+ ms.StoreMessageInfo(mi)
209209+ }
210210+ return ms
211211+ }
212212+ return mi.MessageOf(x)
213213+}
214214+215215+// Deprecated: Use CommitLogResponse.ProtoReflect.Descriptor instead.
216216+func (*CommitLogResponse) Descriptor() ([]byte, []int) {
217217+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{2}
218218+}
219219+220220+func (x *CommitLogResponse) GetCommits() []*GitCommit {
221221+ if x != nil {
222222+ return x.Commits
223223+ }
224224+ return nil
225225+}
226226+78227// One chunk of a blob's raw bytes; concatenate in arrival order.
79228type BlobChunk struct {
80229 state protoimpl.MessageState `protogen:"open.v1"`
···8523486235func (x *BlobChunk) Reset() {
87236 *x = BlobChunk{}
8888- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[1]
237237+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[3]
89238 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
90239 ms.StoreMessageInfo(mi)
91240}
···97246func (*BlobChunk) ProtoMessage() {}
9824799248func (x *BlobChunk) ProtoReflect() protoreflect.Message {
100100- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[1]
249249+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[3]
101250 if x != nil {
102251 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
103252 if ms.LoadMessageInfo() == nil {
···110259111260// Deprecated: Use BlobChunk.ProtoReflect.Descriptor instead.
112261func (*BlobChunk) Descriptor() ([]byte, []int) {
113113- return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{1}
262262+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{3}
114263}
115264116265func (x *BlobChunk) GetData() []byte {
···131280132281func (x *CommitsRequest) Reset() {
133282 *x = CommitsRequest{}
134134- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[2]
283283+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[4]
135284 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
136285 ms.StoreMessageInfo(mi)
137286}
···143292func (*CommitsRequest) ProtoMessage() {}
144293145294func (x *CommitsRequest) ProtoReflect() protoreflect.Message {
146146- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[2]
295295+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[4]
147296 if x != nil {
148297 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
149298 if ms.LoadMessageInfo() == nil {
···156305157306// Deprecated: Use CommitsRequest.ProtoReflect.Descriptor instead.
158307func (*CommitsRequest) Descriptor() ([]byte, []int) {
159159- return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{2}
308308+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{4}
160309}
161310162311func (x *CommitsRequest) GetRepo() string {
···181330182331func (x *CommitsOptions) Reset() {
183332 *x = CommitsOptions{}
184184- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[3]
333333+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[5]
185334 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
186335 ms.StoreMessageInfo(mi)
187336}
···193342func (*CommitsOptions) ProtoMessage() {}
194343195344func (x *CommitsOptions) ProtoReflect() protoreflect.Message {
196196- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[3]
345345+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[5]
197346 if x != nil {
198347 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
199348 if ms.LoadMessageInfo() == nil {
···206355207356// Deprecated: Use CommitsOptions.ProtoReflect.Descriptor instead.
208357func (*CommitsOptions) Descriptor() ([]byte, []int) {
209209- return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{3}
358358+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{5}
210359}
211360212361type CommitsResponse struct {
···219368220369func (x *CommitsResponse) Reset() {
221370 *x = CommitsResponse{}
222222- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[4]
371371+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[6]
223372 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
224373 ms.StoreMessageInfo(mi)
225374}
···231380func (*CommitsResponse) ProtoMessage() {}
232381233382func (x *CommitsResponse) ProtoReflect() protoreflect.Message {
234234- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[4]
383383+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[6]
235384 if x != nil {
236385 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
237386 if ms.LoadMessageInfo() == nil {
···244393245394// Deprecated: Use CommitsResponse.ProtoReflect.Descriptor instead.
246395func (*CommitsResponse) Descriptor() ([]byte, []int) {
247247- return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{4}
396396+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{6}
248397}
249398250399func (x *CommitsResponse) GetCommits() []string {
···267416268417func (x *DiffRequest) Reset() {
269418 *x = DiffRequest{}
270270- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[5]
419419+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[7]
271420 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
272421 ms.StoreMessageInfo(mi)
273422}
···279428func (*DiffRequest) ProtoMessage() {}
280429281430func (x *DiffRequest) ProtoReflect() protoreflect.Message {
282282- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[5]
431431+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[7]
283432 if x != nil {
284433 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
285434 if ms.LoadMessageInfo() == nil {
···292441293442// Deprecated: Use DiffRequest.ProtoReflect.Descriptor instead.
294443func (*DiffRequest) Descriptor() ([]byte, []int) {
295295- return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{5}
444444+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{7}
296445}
297446298447func (x *DiffRequest) GetRepo() string {
···331480332481func (x *InterdiffRequest) Reset() {
333482 *x = InterdiffRequest{}
334334- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[6]
483483+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[8]
335484 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
336485 ms.StoreMessageInfo(mi)
337486}
···343492func (*InterdiffRequest) ProtoMessage() {}
344493345494func (x *InterdiffRequest) ProtoReflect() protoreflect.Message {
346346- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[6]
495495+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[8]
347496 if x != nil {
348497 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
349498 if ms.LoadMessageInfo() == nil {
···356505357506// Deprecated: Use InterdiffRequest.ProtoReflect.Descriptor instead.
358507func (*InterdiffRequest) Descriptor() ([]byte, []int) {
359359- return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{6}
508508+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{8}
360509}
361510362511func (x *InterdiffRequest) GetRepo() string {
···407556408557func (x *FileContent) Reset() {
409558 *x = FileContent{}
410410- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[7]
559559+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[9]
411560 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
412561 ms.StoreMessageInfo(mi)
413562}
···419568func (*FileContent) ProtoMessage() {}
420569421570func (x *FileContent) ProtoReflect() protoreflect.Message {
422422- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[7]
571571+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[9]
423572 if x != nil {
424573 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
425574 if ms.LoadMessageInfo() == nil {
···432581433582// Deprecated: Use FileContent.ProtoReflect.Descriptor instead.
434583func (*FileContent) Descriptor() ([]byte, []int) {
435435- return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{7}
584584+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{9}
436585}
437586438587func (x *FileContent) GetPath() string {
···481630482631func (x *LinePair) Reset() {
483632 *x = LinePair{}
484484- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[8]
633633+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[10]
485634 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
486635 ms.StoreMessageInfo(mi)
487636}
···493642func (*LinePair) ProtoMessage() {}
494643495644func (x *LinePair) ProtoReflect() protoreflect.Message {
496496- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[8]
645645+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[10]
497646 if x != nil {
498647 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
499648 if ms.LoadMessageInfo() == nil {
···506655507656// Deprecated: Use LinePair.ProtoReflect.Descriptor instead.
508657func (*LinePair) Descriptor() ([]byte, []int) {
509509- return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{8}
658658+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{10}
510659}
511660512661func (x *LinePair) GetLhs() uint32 {
···535684536685func (x *Hunk) Reset() {
537686 *x = Hunk{}
538538- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[9]
687687+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[11]
539688 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
540689 ms.StoreMessageInfo(mi)
541690}
···547696func (*Hunk) ProtoMessage() {}
548697549698func (x *Hunk) ProtoReflect() protoreflect.Message {
550550- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[9]
699699+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[11]
551700 if x != nil {
552701 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
553702 if ms.LoadMessageInfo() == nil {
···560709561710// Deprecated: Use Hunk.ProtoReflect.Descriptor instead.
562711func (*Hunk) Descriptor() ([]byte, []int) {
563563- return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{9}
712712+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{11}
564713}
565714566715func (x *Hunk) GetNovelLhs() []uint32 {
···595744596745func (x *ByteChanges) Reset() {
597746 *x = ByteChanges{}
598598- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[10]
747747+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[12]
599748 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
600749 ms.StoreMessageInfo(mi)
601750}
···607756func (*ByteChanges) ProtoMessage() {}
608757609758func (x *ByteChanges) ProtoReflect() protoreflect.Message {
610610- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[10]
759759+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[12]
611760 if x != nil {
612761 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
613762 if ms.LoadMessageInfo() == nil {
···620769621770// Deprecated: Use ByteChanges.ProtoReflect.Descriptor instead.
622771func (*ByteChanges) Descriptor() ([]byte, []int) {
623623- return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{10}
772772+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{12}
624773}
625774626775func (x *ByteChanges) GetLhs() uint64 {
···650799651800func (x *FileDiff) Reset() {
652801 *x = FileDiff{}
653653- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[11]
802802+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[13]
654803 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
655804 ms.StoreMessageInfo(mi)
656805}
···662811func (*FileDiff) ProtoMessage() {}
663812664813func (x *FileDiff) ProtoReflect() protoreflect.Message {
665665- mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[11]
814814+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[13]
666815 if x != nil {
667816 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
668817 if ms.LoadMessageInfo() == nil {
···675824676825// Deprecated: Use FileDiff.ProtoReflect.Descriptor instead.
677826func (*FileDiff) Descriptor() ([]byte, []int) {
678678- return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{11}
827827+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{13}
679828}
680829681830func (x *FileDiff) GetLhsSrc() *FileContent {
···713862 return false
714863}
715864865865+type GitCommit struct {
866866+ state protoimpl.MessageState `protogen:"open.v1"`
867867+ Oid string `protobuf:"bytes,1,opt,name=oid,proto3" json:"oid,omitempty"`
868868+ Author *GitSignature `protobuf:"bytes,2,opt,name=author,proto3" json:"author,omitempty"`
869869+ Committer *GitSignature `protobuf:"bytes,3,opt,name=committer,proto3" json:"committer,omitempty"`
870870+ Message []byte `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"`
871871+ Parents []string `protobuf:"bytes,5,rep,name=parents,proto3" json:"parents,omitempty"`
872872+ unknownFields protoimpl.UnknownFields
873873+ sizeCache protoimpl.SizeCache
874874+}
875875+876876+func (x *GitCommit) Reset() {
877877+ *x = GitCommit{}
878878+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[14]
879879+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
880880+ ms.StoreMessageInfo(mi)
881881+}
882882+883883+func (x *GitCommit) String() string {
884884+ return protoimpl.X.MessageStringOf(x)
885885+}
886886+887887+func (*GitCommit) ProtoMessage() {}
888888+889889+func (x *GitCommit) ProtoReflect() protoreflect.Message {
890890+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[14]
891891+ if x != nil {
892892+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
893893+ if ms.LoadMessageInfo() == nil {
894894+ ms.StoreMessageInfo(mi)
895895+ }
896896+ return ms
897897+ }
898898+ return mi.MessageOf(x)
899899+}
900900+901901+// Deprecated: Use GitCommit.ProtoReflect.Descriptor instead.
902902+func (*GitCommit) Descriptor() ([]byte, []int) {
903903+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{14}
904904+}
905905+906906+func (x *GitCommit) GetOid() string {
907907+ if x != nil {
908908+ return x.Oid
909909+ }
910910+ return ""
911911+}
912912+913913+func (x *GitCommit) GetAuthor() *GitSignature {
914914+ if x != nil {
915915+ return x.Author
916916+ }
917917+ return nil
918918+}
919919+920920+func (x *GitCommit) GetCommitter() *GitSignature {
921921+ if x != nil {
922922+ return x.Committer
923923+ }
924924+ return nil
925925+}
926926+927927+func (x *GitCommit) GetMessage() []byte {
928928+ if x != nil {
929929+ return x.Message
930930+ }
931931+ return nil
932932+}
933933+934934+func (x *GitCommit) GetParents() []string {
935935+ if x != nil {
936936+ return x.Parents
937937+ }
938938+ return nil
939939+}
940940+941941+type GitSignature struct {
942942+ state protoimpl.MessageState `protogen:"open.v1"`
943943+ Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
944944+ Email []byte `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"`
945945+ Date *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=date,proto3" json:"date,omitempty"`
946946+ unknownFields protoimpl.UnknownFields
947947+ sizeCache protoimpl.SizeCache
948948+}
949949+950950+func (x *GitSignature) Reset() {
951951+ *x = GitSignature{}
952952+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[15]
953953+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
954954+ ms.StoreMessageInfo(mi)
955955+}
956956+957957+func (x *GitSignature) String() string {
958958+ return protoimpl.X.MessageStringOf(x)
959959+}
960960+961961+func (*GitSignature) ProtoMessage() {}
962962+963963+func (x *GitSignature) ProtoReflect() protoreflect.Message {
964964+ mi := &file_gitmirror_v1_gitmirror_proto_msgTypes[15]
965965+ if x != nil {
966966+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
967967+ if ms.LoadMessageInfo() == nil {
968968+ ms.StoreMessageInfo(mi)
969969+ }
970970+ return ms
971971+ }
972972+ return mi.MessageOf(x)
973973+}
974974+975975+// Deprecated: Use GitSignature.ProtoReflect.Descriptor instead.
976976+func (*GitSignature) Descriptor() ([]byte, []int) {
977977+ return file_gitmirror_v1_gitmirror_proto_rawDescGZIP(), []int{15}
978978+}
979979+980980+func (x *GitSignature) GetName() []byte {
981981+ if x != nil {
982982+ return x.Name
983983+ }
984984+ return nil
985985+}
986986+987987+func (x *GitSignature) GetEmail() []byte {
988988+ if x != nil {
989989+ return x.Email
990990+ }
991991+ return nil
992992+}
993993+994994+func (x *GitSignature) GetDate() *timestamppb.Timestamp {
995995+ if x != nil {
996996+ return x.Date
997997+ }
998998+ return nil
999999+}
10001000+7161001var File_gitmirror_v1_gitmirror_proto protoreflect.FileDescriptor
71710027181003const file_gitmirror_v1_gitmirror_proto_rawDesc = "" +
7191004 "\n" +
720720- "\x1cgitmirror/v1/gitmirror.proto\x12\fgitmirror.v1\"6\n" +
10051005+ "\x1cgitmirror/v1/gitmirror.proto\x12\fgitmirror.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"6\n" +
7211006 "\x0eGetBlobRequest\x12\x12\n" +
7221007 "\x04repo\x18\x01 \x01(\tR\x04repo\x12\x10\n" +
723723- "\x03oid\x18\x02 \x01(\tR\x03oid\"\x1f\n" +
10081008+ "\x03oid\x18\x02 \x01(\tR\x03oid\"\xf4\x01\n" +
10091009+ "\x10CommitLogRequest\x12\x12\n" +
10101010+ "\x04repo\x18\x01 \x01(\tR\x04repo\x12\x16\n" +
10111011+ "\x06ranges\x18\x02 \x03(\fR\x06ranges\x12\x19\n" +
10121012+ "\ball_refs\x18\x03 \x01(\bR\aallRefs\x120\n" +
10131013+ "\x05after\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\x05after\x122\n" +
10141014+ "\x06before\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\x06before\x12\x1f\n" +
10151015+ "\vmax_commits\x18\x06 \x01(\rR\n" +
10161016+ "maxCommits\x12\x12\n" +
10171017+ "\x04skip\x18\a \x01(\rR\x04skip\"F\n" +
10181018+ "\x11CommitLogResponse\x121\n" +
10191019+ "\acommits\x18\x01 \x03(\v2\x17.gitmirror.v1.GitCommitR\acommits\"\x1f\n" +
7241020 "\tBlobChunk\x12\x12\n" +
7251021 "\x04data\x18\x01 \x01(\fR\x04data\"\\\n" +
7261022 "\x0eCommitsRequest\x12\x12\n" +
···7631059 "\x05hunks\x18\x03 \x03(\v2\x12.gitmirror.v1.HunkR\x05hunks\x12H\n" +
7641060 "\x10has_byte_changes\x18\x04 \x01(\v2\x19.gitmirror.v1.ByteChangesH\x00R\x0ehasByteChanges\x88\x01\x01\x122\n" +
7651061 "\x15has_syntactic_changes\x18\x05 \x01(\bR\x13hasSyntacticChangesB\x13\n" +
766766- "\x11_has_byte_changes2\xa2\x02\n" +
10621062+ "\x11_has_byte_changes\"\xbf\x01\n" +
10631063+ "\tGitCommit\x12\x10\n" +
10641064+ "\x03oid\x18\x01 \x01(\tR\x03oid\x122\n" +
10651065+ "\x06author\x18\x02 \x01(\v2\x1a.gitmirror.v1.GitSignatureR\x06author\x128\n" +
10661066+ "\tcommitter\x18\x03 \x01(\v2\x1a.gitmirror.v1.GitSignatureR\tcommitter\x12\x18\n" +
10671067+ "\amessage\x18\x04 \x01(\fR\amessage\x12\x18\n" +
10681068+ "\aparents\x18\x05 \x03(\tR\aparents\"h\n" +
10691069+ "\fGitSignature\x12\x12\n" +
10701070+ "\x04name\x18\x01 \x01(\fR\x04name\x12\x14\n" +
10711071+ "\x05email\x18\x02 \x01(\fR\x05email\x12.\n" +
10721072+ "\x04date\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\x04date2\xf2\x02\n" +
7671073 "\x10GitMirrorService\x12F\n" +
7681074 "\aCommits\x12\x1c.gitmirror.v1.CommitsRequest\x1a\x1d.gitmirror.v1.CommitsResponse\x12;\n" +
7691075 "\x04Diff\x12\x19.gitmirror.v1.DiffRequest\x1a\x16.gitmirror.v1.FileDiff0\x01\x12E\n" +
7701076 "\tInterdiff\x12\x1e.gitmirror.v1.InterdiffRequest\x1a\x16.gitmirror.v1.FileDiff0\x01\x12B\n" +
771771- "\aGetBlob\x12\x1c.gitmirror.v1.GetBlobRequest\x1a\x17.gitmirror.v1.BlobChunk0\x01B2Z0tangled.org/core/gitmirror/proto/gen;gitmirrorv1b\x06proto3"
10771077+ "\aGetBlob\x12\x1c.gitmirror.v1.GetBlobRequest\x1a\x17.gitmirror.v1.BlobChunk0\x01\x12N\n" +
10781078+ "\tCommitLog\x12\x1e.gitmirror.v1.CommitLogRequest\x1a\x1f.gitmirror.v1.CommitLogResponse0\x01B2Z0tangled.org/core/gitmirror/proto/gen;gitmirrorv1b\x06proto3"
77210797731080var (
7741081 file_gitmirror_v1_gitmirror_proto_rawDescOnce sync.Once
···7821089 return file_gitmirror_v1_gitmirror_proto_rawDescData
7831090}
7841091785785-var file_gitmirror_v1_gitmirror_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
10921092+var file_gitmirror_v1_gitmirror_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
7861093var file_gitmirror_v1_gitmirror_proto_goTypes = []any{
787787- (*GetBlobRequest)(nil), // 0: gitmirror.v1.GetBlobRequest
788788- (*BlobChunk)(nil), // 1: gitmirror.v1.BlobChunk
789789- (*CommitsRequest)(nil), // 2: gitmirror.v1.CommitsRequest
790790- (*CommitsOptions)(nil), // 3: gitmirror.v1.CommitsOptions
791791- (*CommitsResponse)(nil), // 4: gitmirror.v1.CommitsResponse
792792- (*DiffRequest)(nil), // 5: gitmirror.v1.DiffRequest
793793- (*InterdiffRequest)(nil), // 6: gitmirror.v1.InterdiffRequest
794794- (*FileContent)(nil), // 7: gitmirror.v1.FileContent
795795- (*LinePair)(nil), // 8: gitmirror.v1.LinePair
796796- (*Hunk)(nil), // 9: gitmirror.v1.Hunk
797797- (*ByteChanges)(nil), // 10: gitmirror.v1.ByteChanges
798798- (*FileDiff)(nil), // 11: gitmirror.v1.FileDiff
10941094+ (*GetBlobRequest)(nil), // 0: gitmirror.v1.GetBlobRequest
10951095+ (*CommitLogRequest)(nil), // 1: gitmirror.v1.CommitLogRequest
10961096+ (*CommitLogResponse)(nil), // 2: gitmirror.v1.CommitLogResponse
10971097+ (*BlobChunk)(nil), // 3: gitmirror.v1.BlobChunk
10981098+ (*CommitsRequest)(nil), // 4: gitmirror.v1.CommitsRequest
10991099+ (*CommitsOptions)(nil), // 5: gitmirror.v1.CommitsOptions
11001100+ (*CommitsResponse)(nil), // 6: gitmirror.v1.CommitsResponse
11011101+ (*DiffRequest)(nil), // 7: gitmirror.v1.DiffRequest
11021102+ (*InterdiffRequest)(nil), // 8: gitmirror.v1.InterdiffRequest
11031103+ (*FileContent)(nil), // 9: gitmirror.v1.FileContent
11041104+ (*LinePair)(nil), // 10: gitmirror.v1.LinePair
11051105+ (*Hunk)(nil), // 11: gitmirror.v1.Hunk
11061106+ (*ByteChanges)(nil), // 12: gitmirror.v1.ByteChanges
11071107+ (*FileDiff)(nil), // 13: gitmirror.v1.FileDiff
11081108+ (*GitCommit)(nil), // 14: gitmirror.v1.GitCommit
11091109+ (*GitSignature)(nil), // 15: gitmirror.v1.GitSignature
11101110+ (*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp
7991111}
8001112var file_gitmirror_v1_gitmirror_proto_depIdxs = []int32{
801801- 3, // 0: gitmirror.v1.CommitsRequest.options:type_name -> gitmirror.v1.CommitsOptions
802802- 8, // 1: gitmirror.v1.Hunk.lines:type_name -> gitmirror.v1.LinePair
803803- 7, // 2: gitmirror.v1.FileDiff.lhs_src:type_name -> gitmirror.v1.FileContent
804804- 7, // 3: gitmirror.v1.FileDiff.rhs_src:type_name -> gitmirror.v1.FileContent
805805- 9, // 4: gitmirror.v1.FileDiff.hunks:type_name -> gitmirror.v1.Hunk
806806- 10, // 5: gitmirror.v1.FileDiff.has_byte_changes:type_name -> gitmirror.v1.ByteChanges
807807- 2, // 6: gitmirror.v1.GitMirrorService.Commits:input_type -> gitmirror.v1.CommitsRequest
808808- 5, // 7: gitmirror.v1.GitMirrorService.Diff:input_type -> gitmirror.v1.DiffRequest
809809- 6, // 8: gitmirror.v1.GitMirrorService.Interdiff:input_type -> gitmirror.v1.InterdiffRequest
810810- 0, // 9: gitmirror.v1.GitMirrorService.GetBlob:input_type -> gitmirror.v1.GetBlobRequest
811811- 4, // 10: gitmirror.v1.GitMirrorService.Commits:output_type -> gitmirror.v1.CommitsResponse
812812- 11, // 11: gitmirror.v1.GitMirrorService.Diff:output_type -> gitmirror.v1.FileDiff
813813- 11, // 12: gitmirror.v1.GitMirrorService.Interdiff:output_type -> gitmirror.v1.FileDiff
814814- 1, // 13: gitmirror.v1.GitMirrorService.GetBlob:output_type -> gitmirror.v1.BlobChunk
815815- 10, // [10:14] is the sub-list for method output_type
816816- 6, // [6:10] is the sub-list for method input_type
817817- 6, // [6:6] is the sub-list for extension type_name
818818- 6, // [6:6] is the sub-list for extension extendee
819819- 0, // [0:6] is the sub-list for field type_name
11131113+ 16, // 0: gitmirror.v1.CommitLogRequest.after:type_name -> google.protobuf.Timestamp
11141114+ 16, // 1: gitmirror.v1.CommitLogRequest.before:type_name -> google.protobuf.Timestamp
11151115+ 14, // 2: gitmirror.v1.CommitLogResponse.commits:type_name -> gitmirror.v1.GitCommit
11161116+ 5, // 3: gitmirror.v1.CommitsRequest.options:type_name -> gitmirror.v1.CommitsOptions
11171117+ 10, // 4: gitmirror.v1.Hunk.lines:type_name -> gitmirror.v1.LinePair
11181118+ 9, // 5: gitmirror.v1.FileDiff.lhs_src:type_name -> gitmirror.v1.FileContent
11191119+ 9, // 6: gitmirror.v1.FileDiff.rhs_src:type_name -> gitmirror.v1.FileContent
11201120+ 11, // 7: gitmirror.v1.FileDiff.hunks:type_name -> gitmirror.v1.Hunk
11211121+ 12, // 8: gitmirror.v1.FileDiff.has_byte_changes:type_name -> gitmirror.v1.ByteChanges
11221122+ 15, // 9: gitmirror.v1.GitCommit.author:type_name -> gitmirror.v1.GitSignature
11231123+ 15, // 10: gitmirror.v1.GitCommit.committer:type_name -> gitmirror.v1.GitSignature
11241124+ 16, // 11: gitmirror.v1.GitSignature.date:type_name -> google.protobuf.Timestamp
11251125+ 4, // 12: gitmirror.v1.GitMirrorService.Commits:input_type -> gitmirror.v1.CommitsRequest
11261126+ 7, // 13: gitmirror.v1.GitMirrorService.Diff:input_type -> gitmirror.v1.DiffRequest
11271127+ 8, // 14: gitmirror.v1.GitMirrorService.Interdiff:input_type -> gitmirror.v1.InterdiffRequest
11281128+ 0, // 15: gitmirror.v1.GitMirrorService.GetBlob:input_type -> gitmirror.v1.GetBlobRequest
11291129+ 1, // 16: gitmirror.v1.GitMirrorService.CommitLog:input_type -> gitmirror.v1.CommitLogRequest
11301130+ 6, // 17: gitmirror.v1.GitMirrorService.Commits:output_type -> gitmirror.v1.CommitsResponse
11311131+ 13, // 18: gitmirror.v1.GitMirrorService.Diff:output_type -> gitmirror.v1.FileDiff
11321132+ 13, // 19: gitmirror.v1.GitMirrorService.Interdiff:output_type -> gitmirror.v1.FileDiff
11331133+ 3, // 20: gitmirror.v1.GitMirrorService.GetBlob:output_type -> gitmirror.v1.BlobChunk
11341134+ 2, // 21: gitmirror.v1.GitMirrorService.CommitLog:output_type -> gitmirror.v1.CommitLogResponse
11351135+ 17, // [17:22] is the sub-list for method output_type
11361136+ 12, // [12:17] is the sub-list for method input_type
11371137+ 12, // [12:12] is the sub-list for extension type_name
11381138+ 12, // [12:12] is the sub-list for extension extendee
11391139+ 0, // [0:12] is the sub-list for field type_name
8201140}
82111418221142func init() { file_gitmirror_v1_gitmirror_proto_init() }
···8241144 if File_gitmirror_v1_gitmirror_proto != nil {
8251145 return
8261146 }
827827- file_gitmirror_v1_gitmirror_proto_msgTypes[8].OneofWrappers = []any{}
828828- file_gitmirror_v1_gitmirror_proto_msgTypes[11].OneofWrappers = []any{}
11471147+ file_gitmirror_v1_gitmirror_proto_msgTypes[10].OneofWrappers = []any{}
11481148+ file_gitmirror_v1_gitmirror_proto_msgTypes[13].OneofWrappers = []any{}
8291149 type x struct{}
8301150 out := protoimpl.TypeBuilder{
8311151 File: protoimpl.DescBuilder{
8321152 GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
8331153 RawDescriptor: unsafe.Slice(unsafe.StringData(file_gitmirror_v1_gitmirror_proto_rawDesc), len(file_gitmirror_v1_gitmirror_proto_rawDesc)),
8341154 NumEnums: 0,
835835- NumMessages: 12,
11551155+ NumMessages: 16,
8361156 NumExtensions: 0,
8371157 NumServices: 1,
8381158 },
+42-1
gitmirror/proto/gen/gitmirror_grpc.pb.go
···11// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
22// versions:
33-// - protoc-gen-go-grpc v1.6.0
33+// - protoc-gen-go-grpc v1.6.2
44// - protoc (unknown)
55// source: gitmirror/v1/gitmirror.proto
66···2323 GitMirrorService_Diff_FullMethodName = "/gitmirror.v1.GitMirrorService/Diff"
2424 GitMirrorService_Interdiff_FullMethodName = "/gitmirror.v1.GitMirrorService/Interdiff"
2525 GitMirrorService_GetBlob_FullMethodName = "/gitmirror.v1.GitMirrorService/GetBlob"
2626+ GitMirrorService_CommitLog_FullMethodName = "/gitmirror.v1.GitMirrorService/CommitLog"
2627)
27282829// GitMirrorServiceClient is the client API for GitMirrorService service.
···3435 Interdiff(ctx context.Context, in *InterdiffRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[FileDiff], error)
3536 // GetBlob streams a blob's raw bytes by OID, in chunks.
3637 GetBlob(ctx context.Context, in *GetBlobRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[BlobChunk], error)
3838+ CommitLog(ctx context.Context, in *CommitLogRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[CommitLogResponse], error)
3739}
38403941type gitMirrorServiceClient struct {
···111113// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
112114type GitMirrorService_GetBlobClient = grpc.ServerStreamingClient[BlobChunk]
113115116116+func (c *gitMirrorServiceClient) CommitLog(ctx context.Context, in *CommitLogRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[CommitLogResponse], error) {
117117+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
118118+ stream, err := c.cc.NewStream(ctx, &GitMirrorService_ServiceDesc.Streams[3], GitMirrorService_CommitLog_FullMethodName, cOpts...)
119119+ if err != nil {
120120+ return nil, err
121121+ }
122122+ x := &grpc.GenericClientStream[CommitLogRequest, CommitLogResponse]{ClientStream: stream}
123123+ if err := x.ClientStream.SendMsg(in); err != nil {
124124+ return nil, err
125125+ }
126126+ if err := x.ClientStream.CloseSend(); err != nil {
127127+ return nil, err
128128+ }
129129+ return x, nil
130130+}
131131+132132+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
133133+type GitMirrorService_CommitLogClient = grpc.ServerStreamingClient[CommitLogResponse]
134134+114135// GitMirrorServiceServer is the server API for GitMirrorService service.
115136// All implementations must embed UnimplementedGitMirrorServiceServer
116137// for forward compatibility.
···120141 Interdiff(*InterdiffRequest, grpc.ServerStreamingServer[FileDiff]) error
121142 // GetBlob streams a blob's raw bytes by OID, in chunks.
122143 GetBlob(*GetBlobRequest, grpc.ServerStreamingServer[BlobChunk]) error
144144+ CommitLog(*CommitLogRequest, grpc.ServerStreamingServer[CommitLogResponse]) error
123145 mustEmbedUnimplementedGitMirrorServiceServer()
124146}
125147···141163}
142164func (UnimplementedGitMirrorServiceServer) GetBlob(*GetBlobRequest, grpc.ServerStreamingServer[BlobChunk]) error {
143165 return status.Error(codes.Unimplemented, "method GetBlob not implemented")
166166+}
167167+func (UnimplementedGitMirrorServiceServer) CommitLog(*CommitLogRequest, grpc.ServerStreamingServer[CommitLogResponse]) error {
168168+ return status.Error(codes.Unimplemented, "method CommitLog not implemented")
144169}
145170func (UnimplementedGitMirrorServiceServer) mustEmbedUnimplementedGitMirrorServiceServer() {}
146171func (UnimplementedGitMirrorServiceServer) testEmbeddedByValue() {}
···214239// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
215240type GitMirrorService_GetBlobServer = grpc.ServerStreamingServer[BlobChunk]
216241242242+func _GitMirrorService_CommitLog_Handler(srv interface{}, stream grpc.ServerStream) error {
243243+ m := new(CommitLogRequest)
244244+ if err := stream.RecvMsg(m); err != nil {
245245+ return err
246246+ }
247247+ return srv.(GitMirrorServiceServer).CommitLog(m, &grpc.GenericServerStream[CommitLogRequest, CommitLogResponse]{ServerStream: stream})
248248+}
249249+250250+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
251251+type GitMirrorService_CommitLogServer = grpc.ServerStreamingServer[CommitLogResponse]
252252+217253// GitMirrorService_ServiceDesc is the grpc.ServiceDesc for GitMirrorService service.
218254// It's only intended for direct use with grpc.RegisterService,
219255// and not to be introspected or modified (even as a copy)
···240276 {
241277 StreamName: "GetBlob",
242278 Handler: _GitMirrorService_GetBlob_Handler,
279279+ ServerStreams: true,
280280+ },
281281+ {
282282+ StreamName: "CommitLog",
283283+ Handler: _GitMirrorService_CommitLog_Handler,
243284 ServerStreams: true,
244285 },
245286 },
+42
gitmirror/proto/gitmirror/v1/gitmirror.proto
···2233package gitmirror.v1;
4455+import "google/protobuf/timestamp.proto";
66+57option go_package = "tangled.org/core/gitmirror/proto/gen;gitmirrorv1";
6879service GitMirrorService {
···1012 rpc Interdiff(InterdiffRequest) returns (stream FileDiff);
1113 // GetBlob streams a blob's raw bytes by OID, in chunks.
1214 rpc GetBlob(GetBlobRequest) returns (stream BlobChunk);
1515+ rpc CommitLog(CommitLogRequest) returns (stream CommitLogResponse);
1316}
14171518message GetBlobRequest {
···1720 string repo = 1;
1821 // oid is the blob object id (hex).
1922 string oid = 2;
2323+}
2424+2525+message CommitLogRequest {
2626+ // repo DID
2727+ string repo = 1;
2828+ // Ranges to include in the git log (revspec, "A..B", "A...B", etc.).
2929+ // At least one range, or all_refs must be specified.
3030+ repeated bytes ranges = 2;
3131+ // If true, all refs are searched for commits.
3232+ // Must not be true when ranges are given.
3333+ bool all_refs = 3;
3434+ // After is an optional parameter to specify the earliest commit to consider.
3535+ google.protobuf.Timestamp after = 4;
3636+ // Before is an optional parameter to specify the latest commit to consider.
3737+ google.protobuf.Timestamp before = 5;
3838+ // MaxCommits is an optional parameter to specify the maximum number of commits
3939+ // to return. If max_commits is 0, all commits that match the criteria will be
4040+ // returned.
4141+ uint32 max_commits = 6;
4242+ // Skip is an optional parameter to specify the number of commits to skip.
4343+ // This can be used to implement a poor mans pagination.
4444+ uint32 skip = 7;
4545+}
4646+message CommitLogResponse {
4747+ repeated GitCommit commits = 1;
2048}
21492250// One chunk of a blob's raw bytes; concatenate in arrival order.
···95123 bool has_syntactic_changes = 5;
96124 // TODO: lhs_positions / rhs_positions (MatchedPos) — AST, added later.
97125}
126126+127127+message GitCommit {
128128+ string oid = 1;
129129+ GitSignature author = 2;
130130+ GitSignature committer = 3;
131131+ bytes message = 4;
132132+ repeated string parents = 5;
133133+}
134134+135135+message GitSignature {
136136+ bytes name = 1;
137137+ bytes email = 2;
138138+ google.protobuf.Timestamp date = 3;
139139+}
+148-3
gitmirror/src/main.rs
···66use tracing::info;
7788mod diff;
99+mod protocol;
9101011pub mod gitmirror {
1112 pub mod v1 {
···18191920use gix::bstr::ByteSlice as _;
2021use tokio::sync::mpsc;
2222+use tokio_stream::wrappers::ReceiverStream;
2123use tokio_stream::Stream;
2222-use tokio_stream::wrappers::ReceiverStream;
2424+2525+use gix::revision::plumbing::Spec as RevSpec;
2626+use gix::revision::walk::Sorting;
23272428use gitmirror::v1::git_mirror_service_server::{GitMirrorService, GitMirrorServiceServer};
2529use gitmirror::v1::{
2626- BlobChunk, ByteChanges, CommitsRequest, CommitsResponse, DiffRequest, FileContent, FileDiff,
2727- GetBlobRequest, Hunk, InterdiffRequest, LinePair,
3030+ BlobChunk, ByteChanges, CommitLogRequest, CommitLogResponse, CommitsRequest, CommitsResponse,
3131+ DiffRequest, FileContent, FileDiff, GetBlobRequest, GitCommit, GitSignature, Hunk,
3232+ InterdiffRequest, LinePair,
2833};
29343035type FileDiffStream = Pin<Box<dyn Stream<Item = Result<FileDiff, Status>> + Send>>;
3136type BlobChunkStream = Pin<Box<dyn Stream<Item = Result<BlobChunk, Status>> + Send>>;
3737+type CommitLogResponseStream = Pin<Box<dyn Stream<Item = Result<CommitLogResponse, Status>> + Send>>;
32383339/// Blob bytes are streamed in chunks of this size.
3440const BLOB_CHUNK_SIZE: usize = 64 * 1024;
4141+/// GitCommits are streamed in batches of this size.
4242+const COMMIT_LOG_BATCH_SIZE: usize = 128;
35433644#[derive(Parser)]
3745#[command(name = "gitmirror", about = "Git mirror gRPC service")]
···5765 gix::open(self.repo_base.join(did))
5866 .map_err(|e| Status::not_found(format!("repo not found: {e}")))
5967 }
6868+6969+}
7070+7171+/// Resolve tips/hidden commits from a [`CommitLogRequest`] and return the resulting gix walk,
7272+/// sorted newest-first to match `git log`'s default order.
7373+fn commit_log_walk<'repo>(
7474+ repo: &'repo gix::Repository,
7575+ req: &CommitLogRequest,
7676+) -> anyhow::Result<gix::revision::Walk<'repo>> {
7777+ let mut tips = Vec::new();
7878+ let mut hidden = Vec::new();
7979+8080+ if req.all_refs {
8181+ for r in repo.references()?.all()? {
8282+ let mut r = r.map_err(|e| anyhow::anyhow!(e))?;
8383+ if let Ok(commit) = r.peel_to_commit() {
8484+ tips.push(commit.id);
8585+ }
8686+ }
8787+ } else {
8888+ for range in &req.ranges {
8989+ let revspec = repo.rev_parse(range.as_bstr())?;
9090+ let spec = revspec.detach();
9191+ match spec {
9292+ RevSpec::Include(id) => tips.push(id),
9393+ RevSpec::Range { from, to } => {
9494+ tips.push(to);
9595+ hidden.push(from);
9696+ }
9797+ _ => {
9898+ anyhow::bail!("The spec isn't currently supported: {spec:?}")
9999+ }
100100+ }
101101+ }
102102+ }
103103+104104+ Ok(repo
105105+ .rev_walk(tips)
106106+ .sorting(Sorting::ByCommitTime(Default::default()))
107107+ .with_hidden(hidden)
108108+ .all()?)
60109}
6111062111#[tonic::async_trait]
···147196148197 Ok(Response::new(Box::pin(ReceiverStream::new(rx))))
149198 }
199199+200200+ type CommitLogStream = CommitLogResponseStream;
201201+202202+ async fn commit_log(
203203+ &self,
204204+ request: Request<CommitLogRequest>,
205205+ ) -> Result<Response<Self::CommitLogStream>, Status> {
206206+ let req = request.into_inner();
207207+ if req.all_refs == req.ranges.is_empty() {
208208+ return Err(Status::invalid_argument(
209209+ "specify exactly one of `ranges` or `all_refs`",
210210+ ));
211211+ }
212212+ let repo = self.open_repo(&req.repo)?;
213213+ let safe = repo.into_sync();
214214+215215+ let (tx, rx) = mpsc::channel::<Result<CommitLogResponse, Status>>(16);
216216+ tokio::task::spawn_blocking(move || {
217217+ let repo = safe.to_thread_local();
218218+ let run = || -> anyhow::Result<()> {
219219+ let after = req.after.map(|t| t.seconds);
220220+ let before = req.before.map(|t| t.seconds);
221221+ let max_commits = req.max_commits as usize;
222222+ let mut skip = req.skip as usize;
223223+ let mut sent = 0usize;
224224+ let mut batch = Vec::with_capacity(COMMIT_LOG_BATCH_SIZE);
225225+226226+ for info in commit_log_walk(&repo, &req)? {
227227+ let info = info?;
228228+ let commit_time = info.commit_time();
229229+ if before.is_some_and(|b| commit_time > b) {
230230+ continue;
231231+ }
232232+ if after.is_some_and(|a| commit_time < a) {
233233+ break; // newest-first order: nothing older will match either
234234+ }
235235+ if skip > 0 {
236236+ skip -= 1;
237237+ continue;
238238+ }
239239+ if max_commits != 0 && sent >= max_commits {
240240+ break;
241241+ }
242242+ batch.push(GitCommit::try_from(&info.object()?)?);
243243+ sent += 1;
244244+ if batch.len() == COMMIT_LOG_BATCH_SIZE {
245245+ let msg = CommitLogResponse {
246246+ commits: std::mem::take(&mut batch),
247247+ };
248248+ if tx.blocking_send(Ok(msg)).is_err() {
249249+ return Ok(()); // client hung up
250250+ }
251251+ }
252252+ }
253253+ if !batch.is_empty() {
254254+ let _ = tx.blocking_send(Ok(CommitLogResponse { commits: batch }));
255255+ }
256256+ Ok(())
257257+ };
258258+ if let Err(e) = run() {
259259+ let _ = tx.blocking_send(Err(Status::internal(e.to_string())));
260260+ }
261261+ });
262262+263263+ Ok(Response::new(Box::pin(ReceiverStream::new(rx))))
264264+ }
150265}
151266152267/// Resolve a commit-ish ref string (oid, short oid, branch/tag) to its tree oid.
···181296 size: f.size as u64,
182297 is_binary: f.is_binary,
183298 is_submodule: f.is_submodule,
299299+ }
300300+}
301301+302302+impl TryFrom<&gix::Commit<'_>> for GitCommit {
303303+ type Error = anyhow::Error;
304304+305305+ fn try_from(commit: &gix::Commit<'_>) -> anyhow::Result<Self> {
306306+ Ok(GitCommit {
307307+ oid: commit.id.to_string(),
308308+ author: Some(commit.author()?.try_into()?),
309309+ committer: Some(commit.committer()?.try_into()?),
310310+ message: commit.message_raw()?.to_vec(),
311311+ parents: commit.parent_ids().map(|id| id.to_string()).collect(),
312312+ })
313313+ }
314314+}
315315+316316+impl TryFrom<gix::actor::SignatureRef<'_>> for GitSignature {
317317+ type Error = anyhow::Error;
318318+319319+ fn try_from(sig: gix::actor::SignatureRef<'_>) -> anyhow::Result<Self> {
320320+ let time = sig.time()?;
321321+ Ok(GitSignature {
322322+ name: sig.name.to_vec(),
323323+ email: sig.email.to_vec(),
324324+ date: Some(prost_types::Timestamp {
325325+ seconds: time.seconds,
326326+ nanos: 0,
327327+ }),
328328+ })
184329 }
185330}
186331
+3
gitmirror/src/protocol.rs
···11+// pub mod v1 {
22+// tonic::include_proto!("gitmirror.v1");
33+// }