Introduce optimistic locking support via optional parameter last_commit_id on File Update API

This commit is contained in:
Roman Safronov 2017-06-06 13:55:29 +00:00 committed by Grzegorz Bizon
parent 9f3a1203df
commit 1110def8e2
4 changed files with 33 additions and 2 deletions

View file

@ -0,0 +1,4 @@
---
title: 'Introduce optimistic locking support via optional parameter last_commit_sha on File Update API'
merge_request: 11694
author: electroma

View file

@ -111,6 +111,7 @@ Parameters:
- `author_name` (optional) - Specify the commit author's name
- `content` (required) - New file content
- `commit_message` (required) - Commit message
- `last_commit_id` (optional) - Last known file commit id
If the commit fails for any reason we return a 400 error with a non-specific
error message. Possible causes for a failed commit include:

View file

@ -10,7 +10,8 @@ module API
file_content: attrs[:content],
file_content_encoding: attrs[:encoding],
author_email: attrs[:author_email],
author_name: attrs[:author_name]
author_name: attrs[:author_name],
last_commit_sha: attrs[:last_commit_id]
}
end
@ -46,6 +47,7 @@ module API
use :simple_file_params
requires :content, type: String, desc: 'File content'
optional :encoding, type: String, values: %w[base64], desc: 'File encoding'
optional :last_commit_id, type: String, desc: 'Last known commit id for this file'
end
end
@ -111,7 +113,12 @@ module API
authorize! :push_code, user_project
file_params = declared_params(include_missing: false)
begin
result = ::Files::UpdateService.new(user_project, current_user, commit_params(file_params)).execute
rescue ::Files::UpdateService::FileChangedError => e
render_api_error!(e.message, 400)
end
if result[:status] == :success
status(200)

View file

@ -258,6 +258,25 @@ describe API::Files do
expect(last_commit.author_name).to eq(user.name)
end
it "returns a 400 bad request if update existing file with stale last commit id" do
params_with_stale_id = valid_params.merge(last_commit_id: 'stale')
put api(route(file_path), user), params_with_stale_id
expect(response).to have_http_status(400)
expect(json_response['message']).to eq('You are attempting to update a file that has changed since you started editing it.')
end
it "updates existing file in project repo with accepts correct last commit id" do
last_commit = Gitlab::Git::Commit
.last_for_path(project.repository, 'master', URI.unescape(file_path))
params_with_correct_id = valid_params.merge(last_commit_id: last_commit.id)
put api(route(file_path), user), params_with_correct_id
expect(response).to have_http_status(200)
end
it "returns a 400 bad request if no params given" do
put api(route(file_path), user)