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:
authorToon Claes <toon@gitlab.com>2021-05-27 14:14:43 +0300
committerToon Claes <toon@gitlab.com>2021-05-27 14:14:43 +0300
commit57386ae0550bd6e01191724e25b6e77ad09c6288 (patch)
treebc14c18eeed0aaf9476ccc292f6c76d0abaf1efc
parent6e58da454633a53c86d14a59587ee7a6a9d11031 (diff)
parent9cd44c23e4c444438192c0a961e399e2e27ef14b (diff)
Merge branch 'zj-remove-ruby-conflict-resolution' into 'master'
ResolveConflicts: Remove Ruby implementation Closes #3289 See merge request gitlab-org/gitaly!3546
-rw-r--r--internal/gitaly/rubyserver/rubyserver.go8
-rw-r--r--ruby/lib/gitaly_server.rb2
-rw-r--r--ruby/lib/gitaly_server/conflicts_service.rb38
-rw-r--r--ruby/lib/gitlab/git/conflict/file.rb97
-rw-r--r--ruby/lib/gitlab/git/conflict/parser.rb86
-rw-r--r--ruby/lib/gitlab/git/conflict/resolution.rb15
-rw-r--r--ruby/lib/gitlab/git/conflict/resolver.rb98
7 files changed, 0 insertions, 344 deletions
diff --git a/internal/gitaly/rubyserver/rubyserver.go b/internal/gitaly/rubyserver/rubyserver.go
index 237b01c42..03638f7df 100644
--- a/internal/gitaly/rubyserver/rubyserver.go
+++ b/internal/gitaly/rubyserver/rubyserver.go
@@ -188,14 +188,6 @@ func (s *Server) WikiServiceClient(ctx context.Context) (gitalypb.WikiServiceCli
return gitalypb.NewWikiServiceClient(conn), err
}
-// ConflictsServiceClient returns a ConflictsServiceClient instance that is
-// configured to connect to the running Ruby server. This assumes Start()
-// has been called already.
-func (s *Server) ConflictsServiceClient(ctx context.Context) (gitalypb.ConflictsServiceClient, error) {
- conn, err := s.getConnection(ctx)
- return gitalypb.NewConflictsServiceClient(conn), err
-}
-
// RemoteServiceClient returns a RemoteServiceClient instance that is
// configured to connect to the running Ruby server. This assumes Start()
// has been called already.
diff --git a/ruby/lib/gitaly_server.rb b/ruby/lib/gitaly_server.rb
index 33b6e6862..a7526291b 100644
--- a/ruby/lib/gitaly_server.rb
+++ b/ruby/lib/gitaly_server.rb
@@ -8,7 +8,6 @@ require_relative 'gitaly_server/utils.rb'
require_relative 'gitaly_server/operations_service.rb'
require_relative 'gitaly_server/repository_service.rb'
require_relative 'gitaly_server/wiki_service.rb'
-require_relative 'gitaly_server/conflicts_service.rb'
require_relative 'gitaly_server/remote_service.rb'
require_relative 'gitaly_server/health_service.rb'
require_relative 'gitaly_server/feature_flags.rb'
@@ -50,7 +49,6 @@ module GitalyServer
server.handle(OperationsService.new)
server.handle(RepositoryService.new)
server.handle(WikiService.new)
- server.handle(ConflictsService.new)
server.handle(RemoteService.new)
server.handle(HealthService.new)
end
diff --git a/ruby/lib/gitaly_server/conflicts_service.rb b/ruby/lib/gitaly_server/conflicts_service.rb
deleted file mode 100644
index 5173a5135..000000000
--- a/ruby/lib/gitaly_server/conflicts_service.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-module GitalyServer
- class ConflictsService < Gitaly::ConflictsService::Service
- include Utils
-
- def resolve_conflicts(call)
- header = nil
- files_json = ""
-
- call.each_remote_read.each_with_index do |request, index|
- if index.zero?
- header = request.header
- else
- files_json << request.files_json
- end
- end
-
- repo = Gitlab::Git::Repository.from_gitaly(header.repository, call)
- remote_repo = Gitlab::Git::GitalyRemoteRepository.new(header.target_repository, call)
- resolver = Gitlab::Git::Conflict::Resolver.new(remote_repo, header.our_commit_oid, header.their_commit_oid)
- user = Gitlab::Git::User.from_gitaly(header.user)
- files = JSON.parse(files_json).map(&:with_indifferent_access)
-
- begin
- resolution = Gitlab::Git::Conflict::Resolution.new(user, files, header.commit_message.dup)
- params = {
- source_branch: header.source_branch,
- target_branch: header.target_branch,
- timestamp: header.timestamp
- }
- resolver.resolve_conflicts(repo, resolution, params)
-
- Gitaly::ResolveConflictsResponse.new
- rescue Gitlab::Git::Conflict::Resolver::ResolutionError => e
- Gitaly::ResolveConflictsResponse.new(resolution_error: e.message)
- end
- end
- end
-end
diff --git a/ruby/lib/gitlab/git/conflict/file.rb b/ruby/lib/gitlab/git/conflict/file.rb
deleted file mode 100644
index 762b82707..000000000
--- a/ruby/lib/gitlab/git/conflict/file.rb
+++ /dev/null
@@ -1,97 +0,0 @@
-module Gitlab
- module Git
- module Conflict
- class File
- UnsupportedEncoding = Class.new(StandardError)
-
- attr_reader :their_path, :our_path, :our_mode, :ancestor_path, :repository, :commit_oid
-
- attr_accessor :raw_content
-
- def initialize(repository, commit_oid, conflict, raw_content)
- @repository = repository
- @commit_oid = commit_oid
- @their_path = conflict[:theirs][:path]
- @our_path = conflict[:ours][:path]
- @our_mode = conflict[:ours][:mode]
- @ancestor_path = conflict.dig(:ancestor, :path)
- @raw_content = raw_content
- end
-
- def lines
- return @lines if defined?(@lines)
-
- begin
- @type = 'text'
- @lines = Gitlab::Git::Conflict::Parser.parse(content,
- our_path: our_path,
- their_path: their_path)
- rescue Gitlab::Git::Conflict::Parser::ParserError
- @type = 'text-editor'
- @lines = nil
- end
- end
-
- def content
- @content ||= @raw_content.dup.force_encoding('UTF-8')
-
- raise UnsupportedEncoding unless @content.valid_encoding?
-
- @content
- end
-
- def type
- lines unless @type
-
- @type.inquiry
- end
-
- def our_blob
- # REFACTOR NOTE: the source of `commit_oid` used to be
- # `merge_request.diff_refs.head_sha`. Instead of passing this value
- # around the new lib structure, I decided to use `@commit_oid` which is
- # equivalent to `merge_request.source_branch_head.raw.rugged_commit.oid`.
- # That is what `merge_request.diff_refs.head_sha` is equivalent to when
- # `merge_request` is not persisted (see `MergeRequest#diff_head_commit`).
- # I think using the same oid is more consistent anyways, but if Conflicts
- # start breaking, the change described above is a good place to look at.
- @our_blob ||= repository.blob_at(@commit_oid, our_path)
- end
-
- def line_code(line)
- Gitlab::Git.diff_line_code(our_path, line[:line_new], line[:line_old])
- end
-
- def resolve_lines(resolution)
- section_id = nil
-
- lines.map do |line|
- unless line[:type]
- section_id = nil
- next line
- end
-
- section_id ||= line_code(line)
-
- case resolution[section_id]
- when 'head'
- next unless line[:type] == 'new'
- when 'origin'
- next unless line[:type] == 'old'
- else
- raise Gitlab::Git::Conflict::Resolver::ResolutionError, "Missing resolution for section ID: #{section_id}"
- end
-
- line
- end.compact
- end
-
- def resolve_content(resolution)
- raise Gitlab::Git::Conflict::Resolver::ResolutionError, "Resolved content has no changes for file #{our_path}" if resolution == content
-
- resolution
- end
- end
- end
- end
-end
diff --git a/ruby/lib/gitlab/git/conflict/parser.rb b/ruby/lib/gitlab/git/conflict/parser.rb
deleted file mode 100644
index fb5717dd5..000000000
--- a/ruby/lib/gitlab/git/conflict/parser.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-module Gitlab
- module Git
- module Conflict
- class Parser
- UnresolvableError = Class.new(StandardError)
- UnmergeableFile = Class.new(UnresolvableError)
-
- # Recoverable errors - the conflict can be resolved in an editor, but not with
- # sections.
- ParserError = Class.new(StandardError)
- UnexpectedDelimiter = Class.new(ParserError)
- MissingEndDelimiter = Class.new(ParserError)
-
- class << self
- def parse(text, our_path:, their_path:, parent_file: nil)
- validate_text!(text)
-
- line_obj_index = 0
- line_old = 1
- line_new = 1
- type = nil
- lines = []
- conflict_start = "<<<<<<< #{our_path}"
- conflict_middle = '======='
- conflict_end = ">>>>>>> #{their_path}"
-
- text.each_line.map do |line|
- full_line = line.delete("\n")
-
- if full_line == conflict_start
- validate_delimiter!(type.nil?)
-
- type = 'new'
- elsif full_line == conflict_middle
- validate_delimiter!(type == 'new')
-
- type = 'old'
- elsif full_line == conflict_end
- validate_delimiter!(type == 'old')
-
- type = nil
- elsif line[0] == '\\'
- type = 'nonewline'
- lines << {
- full_line: full_line,
- type: type,
- line_obj_index: line_obj_index,
- line_old: line_old,
- line_new: line_new
- }
- else
- lines << {
- full_line: full_line,
- type: type,
- line_obj_index: line_obj_index,
- line_old: line_old,
- line_new: line_new
- }
-
- line_old += 1 if type != 'new'
- line_new += 1 if type != 'old'
-
- line_obj_index += 1
- end
- end
-
- raise MissingEndDelimiter unless type.nil?
-
- lines
- end
-
- private
-
- def validate_text!(text)
- raise UnmergeableFile if text.blank? # Typically a binary file
- raise UnmergeableFile if text.length > 200.kilobytes
- end
-
- def validate_delimiter!(condition)
- raise UnexpectedDelimiter unless condition
- end
- end
- end
- end
- end
-end
diff --git a/ruby/lib/gitlab/git/conflict/resolution.rb b/ruby/lib/gitlab/git/conflict/resolution.rb
deleted file mode 100644
index ab9be683e..000000000
--- a/ruby/lib/gitlab/git/conflict/resolution.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module Gitlab
- module Git
- module Conflict
- class Resolution
- attr_reader :user, :files, :commit_message
-
- def initialize(user, files, commit_message)
- @user = user
- @files = files
- @commit_message = commit_message
- end
- end
- end
- end
-end
diff --git a/ruby/lib/gitlab/git/conflict/resolver.rb b/ruby/lib/gitlab/git/conflict/resolver.rb
deleted file mode 100644
index fa4d2743b..000000000
--- a/ruby/lib/gitlab/git/conflict/resolver.rb
+++ /dev/null
@@ -1,98 +0,0 @@
-module Gitlab
- module Git
- module Conflict
- class Resolver
- ListError = Class.new(StandardError)
- ResolutionError = Class.new(StandardError)
-
- def initialize(target_repository, our_commit_oid, their_commit_oid)
- @target_repository = target_repository
- @our_commit_oid = our_commit_oid
- @their_commit_oid = their_commit_oid
- end
-
- def conflicts
- @conflicts = rugged_list_conflict_files
- rescue Rugged::ReferenceError, Rugged::OdbError => e
- raise ListError, e
- end
-
- def resolve_conflicts(source_repository, resolution, source_branch:, target_branch:, timestamp: nil)
- rugged_resolve_conflicts(source_repository, resolution, source_branch, target_branch, timestamp: timestamp)
- end
-
- def conflict_for_path(conflicts, old_path, new_path)
- conflicts.find do |conflict|
- conflict.their_path == old_path && conflict.our_path == new_path
- end
- end
-
- private
-
- def conflict_files(repository, index)
- index.conflicts.map do |conflict|
- raise ListError, 'conflict side missing' unless conflict[:theirs] && conflict[:ours]
-
- Gitlab::Git::Conflict::File.new(
- repository,
- @our_commit_oid,
- conflict,
- index.merge_file(conflict[:ours][:path])[:data]
- )
- end
- end
-
- def write_resolved_file_to_index(repository, index, file, params)
- if params[:sections]
- resolved_lines = file.resolve_lines(params[:sections])
- new_file = resolved_lines.map { |line| line[:full_line] }.join("\n")
-
- new_file << "\n" if file.our_blob.data.end_with?("\n")
- elsif params[:content]
- new_file = file.resolve_content(params[:content])
- end
-
- our_path = file.our_path
-
- oid = repository.rugged.write(new_file, :blob)
- index.add(path: our_path, oid: oid, mode: file.our_mode)
- index.conflict_remove(our_path)
- end
-
- def rugged_list_conflict_files
- target_index = @target_repository.rugged.merge_commits(@our_commit_oid, @their_commit_oid)
-
- # We don't need to do `with_repo_branch_commit` here, because the target
- # project always fetches source refs when creating merge request diffs.
- conflict_files(@target_repository, target_index)
- end
-
- def rugged_resolve_conflicts(source_repository, resolution, source_branch, target_branch, timestamp: nil)
- source_repository.with_repo_branch_commit(@target_repository, target_branch) do
- index = source_repository.rugged.merge_commits(@our_commit_oid, @their_commit_oid)
- conflicts = conflict_files(source_repository, index)
-
- resolution.files.each do |file_params|
- conflict_file = conflict_for_path(conflicts, file_params[:old_path], file_params[:new_path])
-
- write_resolved_file_to_index(source_repository, index, conflict_file, file_params)
- end
-
- unless index.conflicts.empty?
- missing_files = index.conflicts.map { |file| file[:ours][:path] }
-
- raise ResolutionError, "Missing resolutions for the following files: #{missing_files.join(', ')}"
- end
-
- commit_params = {
- message: resolution.commit_message,
- parents: [@our_commit_oid, @their_commit_oid]
- }
-
- source_repository.commit_index(resolution.user, source_branch, index, commit_params, timestamp)
- end
- end
- end
- end
- end
-end