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:
authorJustin Tobler <jtobler@gitlab.com>2024-01-24 02:25:39 +0300
committerJustin Tobler <jtobler@gitlab.com>2024-01-24 02:29:07 +0300
commit49fe20da31efed5409b61bc1a982ade70257d924 (patch)
tree58c45fd64dbb8357bff138f1dfe1c4cc5a1d37b2
parent3b05eed08cd3df1fbad197a6290a06e683ffba0d (diff)
diff: Introduce `DiffBlob` RPCjt/diff-blob
-rw-r--r--internal/gitaly/service/diff/diff_blob.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/internal/gitaly/service/diff/diff_blob.go b/internal/gitaly/service/diff/diff_blob.go
new file mode 100644
index 000000000..6a13f1b70
--- /dev/null
+++ b/internal/gitaly/service/diff/diff_blob.go
@@ -0,0 +1,68 @@
+package diff
+
+import (
+ "fmt"
+
+ "gitlab.com/gitlab-org/gitaly/v16/internal/git"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/diff"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
+ "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
+)
+
+func (s *server) DiffBlob(in *gitalypb.DiffBlobRequest, stream gitalypb.DiffService_DiffBlobServer) error {
+ ctx := stream.Context()
+
+ repo := s.localrepo(in.GetRepository())
+
+ objectHash, err := repo.ObjectHash(ctx)
+ if err != nil {
+ return fmt.Errorf("detecting object format: %w", err)
+ }
+
+ gitCmd := git.Command{
+ Name: "diff",
+ Flags: []git.Option{
+ // The diff parser requires raw output even if only a single diff is generated.
+ git.Flag{Name: "--raw"},
+ git.Flag{Name: "--patch"},
+ git.Flag{Name: fmt.Sprintf("--abbrev=%d", objectHash.EncodedLen())},
+ git.Flag{Name: "--full-index"},
+ git.Flag{Name: "--no-prefix"},
+ },
+ Args: []string{in.LeftCommitId, in.RightCommitId},
+ }
+
+ cmd, err := repo.Exec(ctx, gitCmd, git.WithSetupStdout())
+ if err != nil {
+ return structerr.NewInternal("cmd: %w", err)
+ }
+
+ diffParser := diff.NewDiffParser(objectHash, cmd, diff.Limits{})
+
+ if !diffParser.Parse() {
+ return structerr.NewInternal("something went wrong")
+ }
+
+ blobDiff := diffParser.Diff()
+
+ if diffParser.Err() != nil {
+ return err
+ }
+
+ for len(blobDiff.Patch) > 0 {
+ resp := &gitalypb.DiffBlobResponse{
+ Patch: blobDiff.Patch,
+ }
+
+ if len(resp.Patch) > s.MsgSizeThreshold {
+ resp.Patch = blobDiff.Patch[:s.MsgSizeThreshold]
+ blobDiff.Patch = blobDiff.Patch[s.MsgSizeThreshold:]
+ }
+
+ if err := stream.Send(resp); err != nil {
+ return structerr.NewAborted("send: %w", err)
+ }
+ }
+
+ return nil
+}