diff --git a/internal/gitaly/service/operations/branches.go b/internal/gitaly/service/operations/branches.go index c6b39eb73318785c4fdfce11c92600102a563ca0..9b3a19dc41b6bb2d72704a866e085c57de7f50dc 100644 --- a/internal/gitaly/service/operations/branches.go +++ b/internal/gitaly/service/operations/branches.go @@ -6,7 +6,9 @@ import ( "fmt" "strings" + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "gitlab.com/gitlab-org/gitaly/internal/git" + "gitlab.com/gitlab-org/gitaly/internal/git/catfile" "gitlab.com/gitlab-org/gitaly/internal/git/localrepo" "gitlab.com/gitlab-org/gitaly/internal/git/log" "gitlab.com/gitlab-org/gitaly/internal/gitaly/rubyserver" @@ -38,12 +40,17 @@ func (s *Server) UserCreateBranch(ctx context.Context, req *gitalypb.UserCreateB startPointCommit, err := log.GetCommit(ctx, s.locator, req.Repository, git.Revision(req.StartPoint)) // END TODO if err != nil { - return nil, status.Errorf(codes.FailedPrecondition, "revspec '%s' not found", req.StartPoint) + if catfile.IsNotFound(err) { + return nil, status.Errorf(codes.FailedPrecondition, "revspec '%s' not found", req.StartPoint) + } + + return nil, err } referenceName := fmt.Sprintf("refs/heads/%s", req.BranchName) _, err = localrepo.New(req.Repository, s.cfg).GetReference(ctx, git.ReferenceName(referenceName)) if err == nil { + ctxlogrus.Extract(ctx).Error("branch already exists") return nil, status.Errorf(codes.FailedPrecondition, "Could not update %s. Please refresh and try again.", req.BranchName) } else if !errors.Is(err, git.ErrReferenceNotFound) { return nil, status.Error(codes.Internal, err.Error()) @@ -52,6 +59,7 @@ func (s *Server) UserCreateBranch(ctx context.Context, req *gitalypb.UserCreateB if err := s.updateReferenceWithHooks(ctx, req.Repository, req.User, referenceName, startPointCommit.Id, git.ZeroOID.String()); err != nil { var preReceiveError preReceiveError if errors.As(err, &preReceiveError) { + ctxlogrus.Extract(ctx).WithError(err).Error("failed to create branch") return &gitalypb.UserCreateBranchResponse{ PreReceiveError: preReceiveError.message, }, nil @@ -108,6 +116,7 @@ func (s *Server) userUpdateBranchGo(ctx context.Context, req *gitalypb.UserUpdat referenceName := fmt.Sprintf("refs/heads/%s", req.BranchName) if err := s.updateReferenceWithHooks(ctx, req.Repository, req.User, referenceName, string(req.Newrev), string(req.Oldrev)); err != nil { + ctxlogrus.Extract(ctx).WithError(err).Error("failed to update branch") var preReceiveError preReceiveError if errors.As(err, &preReceiveError) { return &gitalypb.UserUpdateBranchResponse{ @@ -163,12 +172,17 @@ func (s *Server) UserDeleteBranch(ctx context.Context, req *gitalypb.UserDeleteB referenceName := fmt.Sprintf(referenceFmt, req.BranchName) referenceValue, err := localrepo.New(req.Repository, s.cfg).GetReference(ctx, git.ReferenceName(referenceName)) if err != nil { - return nil, status.Errorf(codes.FailedPrecondition, "branch not found: %s", req.BranchName) + if errors.Is(err, git.ErrReferenceNotFound) { + return nil, status.Errorf(codes.FailedPrecondition, "branch not found: %s", req.BranchName) + } + + return nil, err } if err := s.updateReferenceWithHooks(ctx, req.Repository, req.User, referenceName, git.ZeroOID.String(), referenceValue.Target); err != nil { var preReceiveError preReceiveError if errors.As(err, &preReceiveError) { + ctxlogrus.Extract(ctx).WithError(err).Error("failed to delete branch") return &gitalypb.UserDeleteBranchResponse{ PreReceiveError: preReceiveError.message, }, nil diff --git a/internal/gitaly/service/operations/update_branches_test.go b/internal/gitaly/service/operations/update_branches_test.go index f31641202b30114912a6a4f85b73f77c86199c26..859889748bbd5a1d06298bf7de9f69bf7f977f54 100644 --- a/internal/gitaly/service/operations/update_branches_test.go +++ b/internal/gitaly/service/operations/update_branches_test.go @@ -4,6 +4,7 @@ import ( "context" "crypto/sha1" "fmt" + "path/filepath" "testing" "github.com/stretchr/testify/require" @@ -233,6 +234,13 @@ func testFailedUserUpdateBranchDueToHooks(t *testing.T, ctx context.Context) { testRepo, testRepoPath, cleanupFn := testhelper.NewTestRepo(t) defer cleanupFn() + // macOS' default tmp directory is under /var/... but /var itself is a symlink + // to /private/var. The repository path in the environment variables has its symlinked + // evaluated, causing the comparison to fail, thus we evaluate them here already so the + // assertion later works. + testRepoPath, err := filepath.EvalSymlinks(testRepoPath) + require.NoError(t, err) + serverSocketPath, stop := runOperationServiceServer(t) defer stop()