Commits API: Preserve file content in move operations if unspecified
This commit is contained in:
parent
a54352406a
commit
14076062df
6 changed files with 51 additions and 13 deletions
|
@ -272,7 +272,7 @@ GEM
|
|||
gettext_i18n_rails (>= 0.7.1)
|
||||
po_to_json (>= 1.0.0)
|
||||
rails (>= 3.2.0)
|
||||
gitaly-proto (1.1.0)
|
||||
gitaly-proto (1.2.0)
|
||||
grpc (~> 1.0)
|
||||
github-markup (1.7.0)
|
||||
gitlab-markup (1.6.5)
|
||||
|
@ -998,7 +998,7 @@ DEPENDENCIES
|
|||
gettext (~> 3.2.2)
|
||||
gettext_i18n_rails (~> 1.8.0)
|
||||
gettext_i18n_rails_js (~> 1.3)
|
||||
gitaly-proto (~> 1.1.0)
|
||||
gitaly-proto (~> 1.2.0)
|
||||
github-markup (~> 1.7.0)
|
||||
gitlab-markup (~> 1.6.5)
|
||||
gitlab-sidekiq-fetcher
|
||||
|
|
|
@ -8,6 +8,7 @@ module Files
|
|||
transformer = Lfs::FileTransformer.new(project, @branch_name)
|
||||
|
||||
actions = actions_after_lfs_transformation(transformer, params[:actions])
|
||||
actions = transform_move_actions(actions)
|
||||
|
||||
commit_actions!(actions)
|
||||
end
|
||||
|
@ -26,6 +27,16 @@ module Files
|
|||
end
|
||||
end
|
||||
|
||||
# When moving a file, `content: nil` means "use the contents of the previous
|
||||
# file", while `content: ''` means "move the file and set it to empty"
|
||||
def transform_move_actions(actions)
|
||||
actions.map do |action|
|
||||
action[:infer_content] = true if action[:content].nil?
|
||||
|
||||
action
|
||||
end
|
||||
end
|
||||
|
||||
def commit_actions!(actions)
|
||||
repository.multi_action(
|
||||
current_user,
|
||||
|
|
5
changelogs/unreleased/51083-fix-move-api.yml
Normal file
5
changelogs/unreleased/51083-fix-move-api.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: 'Commits API: Preserve file content in move operations if unspecified'
|
||||
merge_request: 23387
|
||||
author:
|
||||
type: fixed
|
|
@ -87,7 +87,7 @@ POST /projects/:id/repository/commits
|
|||
| `action` | string | yes | The action to perform, `create`, `delete`, `move`, `update`, `chmod`|
|
||||
| `file_path` | string | yes | Full path to the file. Ex. `lib/class.rb` |
|
||||
| `previous_path` | string | no | Original full path to the file being moved. Ex. `lib/class1.rb`. Only considered for `move` action. |
|
||||
| `content` | string | no | File content, required for all except `delete` and `chmod`. Optional for `move` |
|
||||
| `content` | string | no | File content, required for all except `delete`, `chmod`, and `move`. Move actions that do not specify `content` will preserve the existing file content, and any other value of `content` will overwrite the file content. |
|
||||
| `encoding` | string | no | `text` or `base64`. `text` is default. |
|
||||
| `last_commit_id` | string | no | Last known file commit id. Will be only considered in update, move and delete actions. |
|
||||
| `execute_filemode` | boolean | no | When `true/false` enables/disables the execute flag on the file. Only considered for `chmod` action. |
|
||||
|
|
|
@ -385,7 +385,8 @@ module Gitlab
|
|||
file_path: encode_binary(action[:file_path]),
|
||||
previous_path: encode_binary(action[:previous_path]),
|
||||
base64_content: action[:encoding] == 'base64',
|
||||
execute_filemode: !!action[:execute_filemode]
|
||||
execute_filemode: !!action[:execute_filemode],
|
||||
infer_content: !!action[:infer_content]
|
||||
)
|
||||
rescue RangeError
|
||||
raise ArgumentError, "Unknown action '#{action[:action]}'"
|
||||
|
|
|
@ -122,26 +122,47 @@ describe Files::MultiService do
|
|||
let(:action) { 'move' }
|
||||
let(:new_file_path) { 'files/ruby/new_popen.rb' }
|
||||
|
||||
let(:result) { subject.execute }
|
||||
let(:blob) { repository.blob_at_branch(branch_name, new_file_path) }
|
||||
|
||||
context 'when original file has been updated' do
|
||||
before do
|
||||
update_file(original_file_path)
|
||||
end
|
||||
|
||||
it 'rejects the commit' do
|
||||
results = subject.execute
|
||||
|
||||
expect(results[:status]).to eq(:error)
|
||||
expect(results[:message]).to match(original_file_path)
|
||||
expect(result[:status]).to eq(:error)
|
||||
expect(result[:message]).to match(original_file_path)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when original file have not been updated' do
|
||||
context 'when original file has not been updated' do
|
||||
it 'moves the file' do
|
||||
results = subject.execute
|
||||
blob = project.repository.blob_at_branch(branch_name, new_file_path)
|
||||
|
||||
expect(results[:status]).to eq(:success)
|
||||
expect(result[:status]).to eq(:success)
|
||||
expect(blob).to be_present
|
||||
expect(blob.data).to eq(file_content)
|
||||
end
|
||||
|
||||
context 'when content is nil' do
|
||||
let(:file_content) { nil }
|
||||
|
||||
it 'moves the existing content untouched' do
|
||||
original_content = repository.blob_at_branch(branch_name, original_file_path).data
|
||||
|
||||
expect(result[:status]).to eq(:success)
|
||||
expect(blob).to be_present
|
||||
expect(blob.data).to eq(original_content)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when content is an empty string' do
|
||||
let(:file_content) { '' }
|
||||
|
||||
it 'moves the file and empties it' do
|
||||
expect(result[:status]).to eq(:success)
|
||||
expect(blob).not_to be_nil
|
||||
expect(blob.data).to eq('')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue