Merge branch '45035-force-push-api' into 'master'
Accept force option on commit via API Closes #45035 See merge request gitlab-org/gitlab-ce!25286
This commit is contained in:
commit
c19c5197e1
|
@ -1 +1 @@
|
|||
1.23.0
|
||||
1.24.0
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -421,7 +421,7 @@ group :ed25519 do
|
|||
end
|
||||
|
||||
# Gitaly GRPC client
|
||||
gem 'gitaly-proto', '~> 1.12.0', require: 'gitaly'
|
||||
gem 'gitaly-proto', '~> 1.13.0', require: 'gitaly'
|
||||
|
||||
gem 'grpc', '~> 1.15.0'
|
||||
|
||||
|
|
|
@ -279,7 +279,7 @@ GEM
|
|||
gettext_i18n_rails (>= 0.7.1)
|
||||
po_to_json (>= 1.0.0)
|
||||
rails (>= 3.2.0)
|
||||
gitaly-proto (1.12.0)
|
||||
gitaly-proto (1.13.0)
|
||||
grpc (~> 1.0)
|
||||
github-markup (1.7.0)
|
||||
gitlab-default_value_for (3.1.1)
|
||||
|
@ -310,7 +310,7 @@ GEM
|
|||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.0)
|
||||
google-protobuf (3.6.1)
|
||||
googleapis-common-protos-types (1.0.2)
|
||||
googleapis-common-protos-types (1.0.3)
|
||||
google-protobuf (~> 3.0)
|
||||
googleauth (0.6.6)
|
||||
faraday (~> 0.12)
|
||||
|
@ -1018,7 +1018,7 @@ DEPENDENCIES
|
|||
gettext (~> 3.2.2)
|
||||
gettext_i18n_rails (~> 1.8.0)
|
||||
gettext_i18n_rails_js (~> 1.3)
|
||||
gitaly-proto (~> 1.12.0)
|
||||
gitaly-proto (~> 1.13.0)
|
||||
github-markup (~> 1.7.0)
|
||||
gitlab-default_value_for (~> 3.1.1)
|
||||
gitlab-markup (~> 1.6.5)
|
||||
|
|
|
@ -11,6 +11,7 @@ module Commits
|
|||
@start_project = params[:start_project] || @project
|
||||
@start_branch = params[:start_branch]
|
||||
@branch_name = params[:branch_name]
|
||||
@force = params[:force] || false
|
||||
end
|
||||
|
||||
def execute
|
||||
|
@ -42,6 +43,10 @@ module Commits
|
|||
@start_branch != @branch_name || @start_project != @project
|
||||
end
|
||||
|
||||
def force?
|
||||
!!@force
|
||||
end
|
||||
|
||||
def validate!
|
||||
validate_permissions!
|
||||
validate_on_branch!
|
||||
|
@ -65,13 +70,13 @@ module Commits
|
|||
end
|
||||
|
||||
def validate_branch_existence!
|
||||
if !project.empty_repo? && different_branch? && repository.branch_exists?(@branch_name)
|
||||
if !project.empty_repo? && different_branch? && repository.branch_exists?(@branch_name) && !force?
|
||||
raise_error("A branch called '#{@branch_name}' already exists. Switch to that branch in order to make changes")
|
||||
end
|
||||
end
|
||||
|
||||
def validate_new_branch_name!
|
||||
result = ValidateNewBranchService.new(project, current_user).execute(@branch_name)
|
||||
result = ValidateNewBranchService.new(project, current_user).execute(@branch_name, force: force?)
|
||||
|
||||
if result[:status] == :error
|
||||
raise_error("Something went wrong when we tried to create '#{@branch_name}' for you: #{result[:message]}")
|
||||
|
|
|
@ -46,7 +46,8 @@ module Files
|
|||
author_email: @author_email,
|
||||
author_name: @author_name,
|
||||
start_project: @start_project,
|
||||
start_branch_name: @start_branch
|
||||
start_branch_name: @start_branch,
|
||||
force: force?
|
||||
)
|
||||
rescue ArgumentError => e
|
||||
raise_error(e)
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
require_relative 'base_service'
|
||||
|
||||
class ValidateNewBranchService < BaseService
|
||||
def execute(branch_name)
|
||||
def execute(branch_name, force: false)
|
||||
valid_branch = Gitlab::GitRefValidator.validate(branch_name)
|
||||
|
||||
unless valid_branch
|
||||
return error('Branch name is invalid')
|
||||
end
|
||||
|
||||
if project.repository.branch_exists?(branch_name)
|
||||
if project.repository.branch_exists?(branch_name) && !force
|
||||
return error('Branch already exists')
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Accept force option to overwrite branch on commit via API
|
||||
merge_request: 25286
|
||||
author:
|
||||
type: added
|
|
@ -79,6 +79,7 @@ POST /projects/:id/repository/commits
|
|||
| `author_email` | string | no | Specify the commit author's email address |
|
||||
| `author_name` | string | no | Specify the commit author's name |
|
||||
| `stats` | boolean | no | Include commit stats. Default is true |
|
||||
| `force` | boolean | no | When `true` overwrites the target branch with a new commit based on the `start_branch` |
|
||||
|
||||
| `actions[]` Attribute | Type | Required | Description |
|
||||
| --------------------- | ---- | -------- | ----------- |
|
||||
|
|
|
@ -99,6 +99,7 @@ module API
|
|||
optional :author_email, type: String, desc: 'Author email for commit'
|
||||
optional :author_name, type: String, desc: 'Author name for commit'
|
||||
optional :stats, type: Boolean, default: true, desc: 'Include commit stats'
|
||||
optional :force, type: Boolean, default: false, desc: 'When `true` overwrites the target branch with a new commit based on the `start_branch`'
|
||||
end
|
||||
post ':id/repository/commits' do
|
||||
authorize_push_to_branch!(params[:branch])
|
||||
|
|
|
@ -853,17 +853,20 @@ module Gitlab
|
|||
true
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/ParameterLists
|
||||
def multi_action(
|
||||
user, branch_name:, message:, actions:,
|
||||
author_email: nil, author_name: nil,
|
||||
start_branch_name: nil, start_repository: self)
|
||||
start_branch_name: nil, start_repository: self,
|
||||
force: false)
|
||||
|
||||
wrapped_gitaly_errors do
|
||||
gitaly_operation_client.user_commit_files(user, branch_name,
|
||||
message, actions, author_email, author_name,
|
||||
start_branch_name, start_repository)
|
||||
start_branch_name, start_repository, force)
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/ParameterLists
|
||||
|
||||
def write_config(full_path:)
|
||||
return unless full_path.present?
|
||||
|
|
|
@ -277,14 +277,14 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/ParameterLists
|
||||
def user_commit_files(
|
||||
user, branch_name, commit_message, actions, author_email, author_name,
|
||||
start_branch_name, start_repository)
|
||||
|
||||
start_branch_name, start_repository, force = false)
|
||||
req_enum = Enumerator.new do |y|
|
||||
header = user_commit_files_request_header(user, branch_name,
|
||||
commit_message, actions, author_email, author_name,
|
||||
start_branch_name, start_repository)
|
||||
start_branch_name, start_repository, force)
|
||||
|
||||
y.yield Gitaly::UserCommitFilesRequest.new(header: header)
|
||||
|
||||
|
@ -319,6 +319,7 @@ module Gitlab
|
|||
|
||||
Gitlab::Git::OperationService::BranchUpdate.from_gitaly(response.branch_update)
|
||||
end
|
||||
# rubocop:enable Metrics/ParameterLists
|
||||
|
||||
def user_commit_patches(user, branch_name, patches)
|
||||
header = Gitaly::UserApplyPatchRequest::Header.new(
|
||||
|
@ -382,9 +383,10 @@ module Gitlab
|
|||
Gitlab::Git::OperationService::BranchUpdate.from_gitaly(response.branch_update)
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/ParameterLists
|
||||
def user_commit_files_request_header(
|
||||
user, branch_name, commit_message, actions, author_email, author_name,
|
||||
start_branch_name, start_repository)
|
||||
start_branch_name, start_repository, force)
|
||||
|
||||
Gitaly::UserCommitFilesRequestHeader.new(
|
||||
repository: @gitaly_repo,
|
||||
|
@ -394,9 +396,11 @@ module Gitlab
|
|||
commit_author_name: encode_binary(author_name),
|
||||
commit_author_email: encode_binary(author_email),
|
||||
start_branch_name: encode_binary(start_branch_name),
|
||||
start_repository: start_repository.gitaly_repository
|
||||
start_repository: start_repository.gitaly_repository,
|
||||
force: force
|
||||
)
|
||||
end
|
||||
# rubocop:enable Metrics/ParameterLists
|
||||
|
||||
def user_commit_files_action_header(action)
|
||||
Gitaly::UserCommitFilesActionHeader.new(
|
||||
|
|
|
@ -235,6 +235,22 @@ describe Files::MultiService do
|
|||
expect(blob).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
context 'when force is set to true and branch already exists' do
|
||||
let(:commit_params) do
|
||||
{
|
||||
commit_message: commit_message,
|
||||
branch_name: 'feature',
|
||||
start_branch: 'master',
|
||||
actions: actions,
|
||||
force: true
|
||||
}
|
||||
end
|
||||
|
||||
it 'is still a success' do
|
||||
expect(subject.execute[:status]).to eq(:success)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_file(path)
|
||||
|
|
Loading…
Reference in New Issue