diff options
author | Kim "BKC" Carlbäcker <kim.carlbacker@gmail.com> | 2018-05-21 18:56:22 +0300 |
---|---|---|
committer | Kim "BKC" Carlbäcker <kim.carlbacker@gmail.com> | 2018-05-23 16:10:34 +0300 |
commit | 20e9a2562b4ebe392955332eef00baf1f2aaba28 (patch) | |
tree | a72dcba05ce65084177e47f7769af89d48e6bc01 | |
parent | 950d2f5e8c28597af1891d1f6015f7d1e0ece8b6 (diff) |
Rewrite Diff::CommitDiff in Ruby
-rw-r--r-- | internal/service/diff/commit.go | 32 | ||||
-rw-r--r-- | ruby/lib/gitaly_server/diff_service.rb | 68 | ||||
-rw-r--r-- | ruby/lib/gitlab/git.rb | 1 | ||||
-rw-r--r-- | ruby/lib/gitlab/git/diff.rb | 27 |
4 files changed, 127 insertions, 1 deletions
diff --git a/internal/service/diff/commit.go b/internal/service/diff/commit.go index 7b5ff8d71..eb8d4a648 100644 --- a/internal/service/diff/commit.go +++ b/internal/service/diff/commit.go @@ -9,6 +9,7 @@ import ( pb "gitlab.com/gitlab-org/gitaly-proto/go" "gitlab.com/gitlab-org/gitaly/internal/diff" "gitlab.com/gitlab-org/gitaly/internal/git" + "gitlab.com/gitlab-org/gitaly/internal/rubyserver" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -19,6 +20,35 @@ type requestWithLeftRightCommitIds interface { } func (s *server) CommitDiff(in *pb.CommitDiffRequest, stream pb.DiffService_CommitDiffServer) error { + ctx := stream.Context() + + client, err := s.DiffServiceClient(ctx) + if err != nil { + return err + } + + clientCtx, err := rubyserver.SetHeaders(ctx, in.GetRepository()) + if err != nil { + return err + } + + rubyStream, err := client.CommitDiff(clientCtx, in) + if err != nil { + return err + } + + return rubyserver.Proxy(func() error { + resp, err := rubyStream.Recv() + if err != nil { + md := rubyStream.Trailer() + stream.SetTrailer(md) + return err + } + return stream.Send(resp) + }) +} + +/* grpc_logrus.Extract(stream.Context()).WithFields(log.Fields{ "LeftCommitId": in.LeftCommitId, "RightCommitId": in.RightCommitId, @@ -111,7 +141,7 @@ func (s *server) CommitDiff(in *pb.CommitDiffRequest, stream pb.DiffService_Comm return nil }) } - +*/ func (s *server) CommitDelta(in *pb.CommitDeltaRequest, stream pb.DiffService_CommitDeltaServer) error { grpc_logrus.Extract(stream.Context()).WithFields(log.Fields{ "LeftCommitId": in.LeftCommitId, diff --git a/ruby/lib/gitaly_server/diff_service.rb b/ruby/lib/gitaly_server/diff_service.rb index 340146ea8..17e9029c9 100644 --- a/ruby/lib/gitaly_server/diff_service.rb +++ b/ruby/lib/gitaly_server/diff_service.rb @@ -15,5 +15,73 @@ module GitalyServer end end end + + def commit_diff(request, call) + bridge_exceptions do + repo = Gitlab::Git::Repository.from_gitaly(request.repository, call) + + options = { + :ignore_whitespace_change => request.ignore_whitespace_change, + :limits => request.enforce_limits, + :expanded => !(request.enforce_limits || request.collapse_diffs), + :max_lines => request.max_lines, + :max_files => request.max_files, + :max_bytes => request.max_bytes, + :safe_max_lines => request.safe_max_lines, + :safe_max_files => request.safe_max_files, + :safe_max_bytes => request.safe_max_bytes, + } + + Enumerator.new do |y| + repo.diff(request.left_commit_id, request.right_commit_id, options, *request.paths.to_a).each do |diff| + response = Gitaly::CommitDiffResponse.new( + :from_path => diff.old_path.b, + :to_path => diff.new_path.b, + :from_id => diff.old_id, + :to_id => diff.new_id, + :old_mode => diff.a_mode.to_i(base=8), + :new_mode => diff.b_mode.to_i(base=8), + :binary => diff.has_binary_notice?, + :overflow_marker => diff.too_large?, + :collapsed => diff.collapsed? + ) + io = StringIO.new(diff.diff) + + chunk = io.read(Gitlab.config.git.write_buffer_size) + chunk = strip_diff_headers(chunk) + response.raw_patch_data = chunk.b + y.yield response + while chunk = io.read(Gitlab.config.git.write_buffer_size) + response.raw_patch_data = chunk.b + y.yield response + end + response.raw_patch_data = "" + response.end_of_patch = true + y.yield response + end + end + end + end + + private + + # Stolen from Gitlab::Git::Diff since that is private + + # Strip out the information at the beginning of the patch's text to match + # Grit's output + def strip_diff_headers(diff_text) + # Delete everything up to the first line that starts with '---' or + # 'Binary' + diff_text.sub!(/\A.*?^(@@ )/m, '\1') + + if diff_text.start_with?('@@ ') + diff_text + else + # If the diff_text did not contain a line starting with '---' or + # 'Binary', return the empty string. No idea why; we are just + # preserving behavior from before the refactor. + '' + end + end end end diff --git a/ruby/lib/gitlab/git.rb b/ruby/lib/gitlab/git.rb index 80516553a..8b4028c8f 100644 --- a/ruby/lib/gitlab/git.rb +++ b/ruby/lib/gitlab/git.rb @@ -44,6 +44,7 @@ end require_relative 'git/gitaly_remote_repository.rb' require_relative 'git/repository.rb' +require_relative 'git/diff.rb' require_relative 'git/gitlab_projects.rb' class String diff --git a/ruby/lib/gitlab/git/diff.rb b/ruby/lib/gitlab/git/diff.rb new file mode 100644 index 000000000..0f5711534 --- /dev/null +++ b/ruby/lib/gitlab/git/diff.rb @@ -0,0 +1,27 @@ +module Gitlab + module Git + # These are monkey patches on top of the vendored version of Diff. + class Diff + attr_reader :old_id, :new_id + + def init_from_rugged(rugged) + if rugged.is_a?(Rugged::Patch) + init_from_rugged_patch(rugged) + d = rugged.delta + else + d = rugged + end + + @new_path = encode!(d.new_file[:path]) + @old_path = encode!(d.old_file[:path]) + @a_mode = d.old_file[:mode].to_s(8) + @b_mode = d.new_file[:mode].to_s(8) + @new_file = d.added? + @renamed_file = d.renamed? + @deleted_file = d.deleted? + @old_id = d.old_file[:oid] || BLANK_SHA + @new_id = d.new_file[:oid] || BLANK_SHA + end + end + end +end |