Commit de5aef3b authored by Patrick Bajao's avatar Patrick Bajao Committed by Nick Thomas

Accept force option on commit via API

When `force` is set to `true` and `start_branch` is set, the
branch will be ovewritten with the new commit based on the
`HEAD` of the `start_branch`.

This commit includes changes to update the `gitaly-proto` gem.
parent c9e5ce8d
1.23.0
\ No newline at end of file
1.24.0
......@@ -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
......
---
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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment