diff options
author | Oswaldo Ferreira <oswaldo@gitlab.com> | 2019-01-10 10:38:15 -0200 |
---|---|---|
committer | Oswaldo Ferreira <oswaldo@gitlab.com> | 2019-01-11 21:35:07 -0200 |
commit | 6e293681180870e16cb102817dd588b0357cabca (patch) | |
tree | 9c0bc2528d35e32f00287ec6509baa2e15874182 /app/services/suggestions | |
parent | 49f538c766f3b4f8fb7436afd472f88291a7c76e (diff) | |
download | gitlab-ce-6e293681180870e16cb102817dd588b0357cabca.tar.gz |
Adjust applied suggestion reverting previous changes
1. Avoid suggestions being applied on the same file
from reverting previous changes
2. Gracefully use and handle file changes error
when updating the file (though, it does not totally
solves the sync problem for multiple suggestion
applications at once)
Diffstat (limited to 'app/services/suggestions')
-rw-r--r-- | app/services/suggestions/apply_service.rb | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/app/services/suggestions/apply_service.rb b/app/services/suggestions/apply_service.rb index d931d528c86..cc47b46b527 100644 --- a/app/services/suggestions/apply_service.rb +++ b/app/services/suggestions/apply_service.rb @@ -11,6 +11,10 @@ module Suggestions return error('Suggestion is not appliable') end + unless latest_diff_refs?(suggestion) + return error('The file has been changed') + end + params = file_update_params(suggestion) result = ::Files::UpdateService.new(suggestion.project, @current_user, params).execute @@ -19,30 +23,44 @@ module Suggestions end result + rescue Files::UpdateService::FileChangedError + error('The file has been changed') end private - def file_update_params(suggestion) - diff_file = suggestion.diff_file + # Checks whether the latest diff refs for the branch matches with + # the position refs we're using to update the file content. Since + # the persisted refs are updated async (for MergeRequest), + # it's more consistent to fetch this data directly from the repository. + def latest_diff_refs?(suggestion) + suggestion.position.diff_refs == suggestion.noteable.repository_diff_refs + end - file_path = diff_file.file_path - branch_name = suggestion.noteable.source_branch - file_content = new_file_content(suggestion) + def file_update_params(suggestion) + blob = suggestion.diff_file.new_blob + file_path = suggestion.file_path + branch_name = suggestion.branch + file_content = new_file_content(suggestion, blob) commit_message = "Apply suggestion to #{file_path}" + file_last_commit = + Gitlab::Git::Commit.last_for_path(suggestion.project.repository, + blob.commit_id, + blob.path) + { file_path: file_path, branch_name: branch_name, start_branch: branch_name, commit_message: commit_message, - file_content: file_content + file_content: file_content, + last_commit_sha: file_last_commit&.id } end - def new_file_content(suggestion) + def new_file_content(suggestion, blob) range = suggestion.from_line_index..suggestion.to_line_index - blob = suggestion.diff_file.new_blob blob.load_all_data! content = blob.data.lines |