Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <psteinhardt@gitlab.com>2020-10-13 14:16:37 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2020-10-15 14:50:07 +0300
commit2f2e703cf4a535ed8b007b3d6123751a9a2baf78 (patch)
tree5c1e95e9f3f0ccb117dec6e63f0dd579fece5687 /cmd/gitaly-git2go
parent8d01fd4b39a645e75a9006860827d8f03c928e2f (diff)
git2go: Refactor conflict error handling
Due to the process-gap between the conflicts service and its Git2Go executable, it's not as straight-forward to pass around information as it usually is. One of those areas which are currently lacking in conflict handling is how we treat error codes. In case there's a potentially expected error happening inside the command, it's currently impossible to tell because all the different errors are lumped together into a single error return code. Address this issue by instead serializing error codes into the result structure. Like this, we can become more informative around the specific error code and discern different cases.
Diffstat (limited to 'cmd/gitaly-git2go')
-rw-r--r--cmd/gitaly-git2go/conflicts.go25
1 files changed, 23 insertions, 2 deletions
diff --git a/cmd/gitaly-git2go/conflicts.go b/cmd/gitaly-git2go/conflicts.go
index df4bda432..f2ba28abd 100644
--- a/cmd/gitaly-git2go/conflicts.go
+++ b/cmd/gitaly-git2go/conflicts.go
@@ -10,6 +10,9 @@ import (
git "github.com/libgit2/git2go/v30"
"gitlab.com/gitlab-org/gitaly/internal/git2go"
+ "gitlab.com/gitlab-org/gitaly/internal/helper"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
)
type conflictsSubcommand struct {
@@ -46,7 +49,7 @@ func conflictContent(repo *git.Repository, conflict git.IndexConflict) ([]byte,
blob, err := repo.LookupBlob(entry.Id)
if err != nil {
- return nil, fmt.Errorf("could not get conflicting blob: %w", err)
+ return nil, helper.ErrPreconditionFailedf("could not get conflicting blob: %w", err)
}
input.Path = entry.Path
@@ -62,6 +65,21 @@ func conflictContent(repo *git.Repository, conflict git.IndexConflict) ([]byte,
return merge.Contents, nil
}
+func conflictError(code codes.Code, message string) error {
+ result := git2go.ConflictsResult{
+ Error: git2go.ConflictError{
+ Code: code,
+ Message: message,
+ },
+ }
+
+ if err := result.SerializeTo(os.Stdout); err != nil {
+ return err
+ }
+
+ return nil
+}
+
// Run performs a merge and prints resulting conflicts to stdout.
func (cmd *conflictsSubcommand) Run() error {
request, err := git2go.ConflictsCommandFromSerialized(cmd.request)
@@ -96,7 +114,7 @@ func (cmd *conflictsSubcommand) Run() error {
index, err := repo.MergeCommits(ours, theirs, nil)
if err != nil {
- return fmt.Errorf("could not merge commits: %w", err)
+ return conflictError(codes.FailedPrecondition, fmt.Sprintf("could not merge commits: %v", err))
}
conflicts, err := index.ConflictIterator()
@@ -117,6 +135,9 @@ func (cmd *conflictsSubcommand) Run() error {
content, err := conflictContent(repo, conflict)
if err != nil {
+ if status, ok := status.FromError(err); ok {
+ return conflictError(status.Code(), status.Message())
+ }
return err
}