1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
package ref
import (
"bufio"
"context"
"gitlab.com/gitlab-org/gitaly/v14/internal/git"
"gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk"
"gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/wrapperspb"
)
// FindAllBranchNames creates a stream of ref names for all branches in the given repository
func (s *server) FindAllBranchNames(in *gitalypb.FindAllBranchNamesRequest, stream gitalypb.RefService_FindAllBranchNamesServer) error {
chunker := chunk.New(&findAllBranchNamesSender{stream: stream})
return s.listRefNames(stream.Context(), chunker, "refs/heads", in.Repository, nil)
}
type findAllBranchNamesSender struct {
stream gitalypb.RefService_FindAllBranchNamesServer
branchNames [][]byte
}
func (ts *findAllBranchNamesSender) Reset() { ts.branchNames = nil }
func (ts *findAllBranchNamesSender) Append(m proto.Message) {
ts.branchNames = append(ts.branchNames, []byte(m.(*wrapperspb.StringValue).Value))
}
func (ts *findAllBranchNamesSender) Send() error {
return ts.stream.Send(&gitalypb.FindAllBranchNamesResponse{Names: ts.branchNames})
}
// FindAllTagNames creates a stream of ref names for all tags in the given repository
func (s *server) FindAllTagNames(in *gitalypb.FindAllTagNamesRequest, stream gitalypb.RefService_FindAllTagNamesServer) error {
chunker := chunk.New(&findAllTagNamesSender{stream: stream})
return s.listRefNames(stream.Context(), chunker, "refs/tags", in.Repository, nil)
}
type findAllTagNamesSender struct {
stream gitalypb.RefService_FindAllTagNamesServer
tagNames [][]byte
}
func (ts *findAllTagNamesSender) Reset() { ts.tagNames = nil }
func (ts *findAllTagNamesSender) Append(m proto.Message) {
ts.tagNames = append(ts.tagNames, []byte(m.(*wrapperspb.StringValue).Value))
}
func (ts *findAllTagNamesSender) Send() error {
return ts.stream.Send(&gitalypb.FindAllTagNamesResponse{Names: ts.tagNames})
}
func (s *server) listRefNames(ctx context.Context, chunker *chunk.Chunker, prefix string, repo *gitalypb.Repository, extraArgs []string) error {
flags := []git.Option{
git.Flag{Name: "--format=%(refname)"},
}
for _, arg := range extraArgs {
flags = append(flags, git.Flag{Name: arg})
}
cmd, err := s.gitCmdFactory.New(ctx, repo, git.SubCmd{
Name: "for-each-ref",
Flags: flags,
Args: []string{prefix},
})
if err != nil {
return err
}
scanner := bufio.NewScanner(cmd)
for scanner.Scan() {
// Important: don't use scanner.Bytes() because the slice will become
// invalid on the next loop iteration. Instead, use scanner.Text() to
// force a copy.
if err := chunker.Send(&wrapperspb.StringValue{Value: scanner.Text()}); err != nil {
return err
}
}
if err := cmd.Wait(); err != nil {
return err
}
if err := scanner.Err(); err != nil {
return err
}
return chunker.Flush()
}
|