diff options
Diffstat (limited to 'internal/gitaly/service/remote/find_remote_repository.go')
-rw-r--r-- | internal/gitaly/service/remote/find_remote_repository.go | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/internal/gitaly/service/remote/find_remote_repository.go b/internal/gitaly/service/remote/find_remote_repository.go new file mode 100644 index 000000000..fa78d023a --- /dev/null +++ b/internal/gitaly/service/remote/find_remote_repository.go @@ -0,0 +1,48 @@ +package remote + +import ( + "bytes" + "context" + "io/ioutil" + + "gitlab.com/gitlab-org/gitaly/v14/internal/git" + "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (s *server) FindRemoteRepository(ctx context.Context, req *gitalypb.FindRemoteRepositoryRequest) (*gitalypb.FindRemoteRepositoryResponse, error) { + if req.GetRemote() == "" { + return nil, status.Error(codes.InvalidArgument, "FindRemoteRepository: empty remote can't be checked.") + } + + cmd, err := s.gitCmdFactory.NewWithoutRepo(ctx, + git.SubCmd{ + Name: "ls-remote", + Args: []string{ + req.GetRemote(), + "HEAD", + }, + }, + ) + + if err != nil { + return nil, status.Errorf(codes.Internal, "error executing git command: %s", err) + } + + output, err := ioutil.ReadAll(cmd) + if err != nil { + return nil, status.Errorf(codes.Internal, "unable to read stdout: %s", err) + } + if err := cmd.Wait(); err != nil { + return &gitalypb.FindRemoteRepositoryResponse{Exists: false}, nil + } + + // The output of a successful command is structured like + // Regexp would've read better, but this is faster + // 58fbff2e0d3b620f591a748c158799ead87b51cd HEAD + fields := bytes.Fields(output) + match := len(fields) == 2 && len(fields[0]) == 40 && string(fields[1]) == "HEAD" + + return &gitalypb.FindRemoteRepositoryResponse{Exists: match}, nil +} |