Commit ebfad5b9 authored by Marin Jankovski's avatar Marin Jankovski

Merge branch 'ce-to-ee-2018-01-06' into 'master'

CE upstream - Saturday

Closes gitlab-development-kit#310 and gitaly#872

See merge request gitlab-org/gitlab-ee!3946
parents 12effe58 26642bfd
...@@ -790,34 +790,30 @@ class Repository ...@@ -790,34 +790,30 @@ class Repository
end end
def create_dir(user, path, **options) def create_dir(user, path, **options)
options[:user] = user
options[:actions] = [{ action: :create_dir, file_path: path }] options[:actions] = [{ action: :create_dir, file_path: path }]
multi_action(**options) multi_action(user, **options)
end end
def create_file(user, path, content, **options) def create_file(user, path, content, **options)
options[:user] = user
options[:actions] = [{ action: :create, file_path: path, content: content }] options[:actions] = [{ action: :create, file_path: path, content: content }]
multi_action(**options) multi_action(user, **options)
end end
def update_file(user, path, content, **options) def update_file(user, path, content, **options)
previous_path = options.delete(:previous_path) previous_path = options.delete(:previous_path)
action = previous_path && previous_path != path ? :move : :update action = previous_path && previous_path != path ? :move : :update
options[:user] = user
options[:actions] = [{ action: action, file_path: path, previous_path: previous_path, content: content }] options[:actions] = [{ action: action, file_path: path, previous_path: previous_path, content: content }]
multi_action(**options) multi_action(user, **options)
end end
def delete_file(user, path, **options) def delete_file(user, path, **options)
options[:user] = user
options[:actions] = [{ action: :delete, file_path: path }] options[:actions] = [{ action: :delete, file_path: path }]
multi_action(**options) multi_action(user, **options)
end end
def with_cache_hooks def with_cache_hooks
...@@ -831,59 +827,14 @@ class Repository ...@@ -831,59 +827,14 @@ class Repository
result.newrev result.newrev
end end
def with_branch(user, *args) def multi_action(user, **options)
with_cache_hooks do start_project = options.delete(:start_project)
Gitlab::Git::OperationService.new(user, raw_repository).with_branch(*args) do |start_commit|
yield start_commit
end
end
end
# rubocop:disable Metrics/ParameterLists
def multi_action(
user:, branch_name:, message:, actions:,
author_email: nil, author_name: nil,
start_branch_name: nil, start_project: project)
with_branch( if start_project
user, options[:start_repository] = start_project.repository.raw_repository
branch_name,
start_branch_name: start_branch_name,
start_repository: start_project.repository.raw_repository) do |start_commit|
index = Gitlab::Git::Index.new(raw_repository)
if start_commit
index.read_tree(start_commit.rugged_commit.tree)
parents = [start_commit.sha]
else
parents = []
end end
actions.each do |options| with_cache_hooks { raw.multi_action(user, **options) }
index.public_send(options.delete(:action), options) # rubocop:disable GitlabSecurity/PublicSend
end
options = {
tree: index.write_tree,
message: message,
parents: parents
}
options.merge!(get_committer_and_author(user, email: author_email, name: author_name))
create_commit(options)
end
end
# rubocop:enable Metrics/ParameterLists
def get_committer_and_author(user, email: nil, name: nil)
committer = user_to_committer(user)
author = Gitlab::Git.committer_hash(email: email, name: name) || committer
{
author: author,
committer: committer
}
end end
def can_be_merged?(source_sha, target_branch) def can_be_merged?(source_sha, target_branch)
......
...@@ -4,7 +4,7 @@ module Files ...@@ -4,7 +4,7 @@ module Files
def create_commit! def create_commit!
repository.multi_action( repository.multi_action(
user: current_user, current_user,
message: @commit_message, message: @commit_message,
branch_name: @branch_name, branch_name: @branch_name,
actions: params[:actions], actions: params[:actions],
...@@ -13,6 +13,8 @@ module Files ...@@ -13,6 +13,8 @@ module Files
start_project: @start_project, start_project: @start_project,
start_branch_name: @start_branch start_branch_name: @start_branch
) )
rescue ArgumentError => e
raise_error(e)
end end
private private
...@@ -20,16 +22,7 @@ module Files ...@@ -20,16 +22,7 @@ module Files
def validate! def validate!
super super
params[:actions].each do |action| params[:actions].each { |action| validate_file_status!(action) }
validate_action!(action)
validate_file_status!(action)
end
end
def validate_action!(action)
unless Gitlab::Git::Index::ACTIONS.include?(action[:action].to_s)
raise_error("Unknown action '#{action[:action]}'")
end
end end
def validate_file_status!(action) def validate_file_status!(action)
......
...@@ -63,7 +63,8 @@ Sidekiq::Testing.inline! do ...@@ -63,7 +63,8 @@ Sidekiq::Testing.inline! do
namespace_id: group.id, namespace_id: group.id,
name: project_path.titleize, name: project_path.titleize,
description: FFaker::Lorem.sentence, description: FFaker::Lorem.sentence,
visibility_level: Gitlab::VisibilityLevel.values.sample visibility_level: Gitlab::VisibilityLevel.values.sample,
skip_disk_validation: true
} }
project = Projects::CreateService.new(User.first, params).execute project = Projects::CreateService.new(User.first, params).execute
......
# See http://doc.gitlab.com/ce/development/migration_style_guide.html # This migration is a duplicate of 20171230123729_add_rebase_commit_sha_to_merge_requests_ce.rb
# for more information on how to write migrations for GitLab. #
# We backported this feature from EE using the same migration, but with a new
# timestamp, which caused an error when the backport was then to be merged back
# into EE.
#
# See discussion at https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3932
class AddRebaseCommitShaToMergeRequests < ActiveRecord::Migration class AddRebaseCommitShaToMergeRequests < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers DOWNTIME = false
# When using the methods "add_concurrent_index" or "add_column_with_default"
# you must disable the use of transactions as these methods can not run in an
# existing transaction. When using "add_concurrent_index" make sure that this
# method is the _only_ method called in the migration, any other changes
# should go in a separate migration. This ensures that upon failure _only_ the
# index creation fails and can be retried or reverted easily.
#
# To disable transactions uncomment the following line and remove these
# comments:
# disable_ddl_transaction!
def change def up
unless column_exists?(:merge_requests, :rebase_commit_sha)
add_column :merge_requests, :rebase_commit_sha, :string add_column :merge_requests, :rebase_commit_sha, :string
end end
end
def down
if column_exists?(:merge_requests, :rebase_commit_sha)
remove_column :merge_requests, :rebase_commit_sha
end
end
end end
...@@ -299,9 +299,9 @@ sudo usermod -aG redis git ...@@ -299,9 +299,9 @@ sudo usermod -aG redis git
### Clone the Source ### Clone the Source
# Clone GitLab repository # Clone GitLab repository
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 10-3-stable gitlab sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 10-4-stable gitlab
**Note:** You can change `10-3-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! **Note:** You can change `10-4-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
### Configure It ### Configure It
......
...@@ -10,6 +10,7 @@ module Gitlab ...@@ -10,6 +10,7 @@ module Gitlab
DEFAULT_MODE = 0o100644 DEFAULT_MODE = 0o100644
ACTIONS = %w(create create_dir update move delete).freeze ACTIONS = %w(create create_dir update move delete).freeze
ACTION_OPTIONS = %i(file_path previous_path content encoding).freeze
attr_reader :repository, :raw_index attr_reader :repository, :raw_index
...@@ -20,6 +21,11 @@ module Gitlab ...@@ -20,6 +21,11 @@ module Gitlab
delegate :read_tree, :get, to: :raw_index delegate :read_tree, :get, to: :raw_index
def apply(action, options)
validate_action!(action)
public_send(action, options.slice(*ACTION_OPTIONS)) # rubocop:disable GitlabSecurity/PublicSend
end
def write_tree def write_tree
raw_index.write_tree(repository.rugged) raw_index.write_tree(repository.rugged)
end end
...@@ -140,6 +146,12 @@ module Gitlab ...@@ -140,6 +146,12 @@ module Gitlab
rescue Rugged::IndexError => e rescue Rugged::IndexError => e
raise IndexError, e.message raise IndexError, e.message
end end
def validate_action!(action)
unless ACTIONS.include?(action.to_s)
raise ArgumentError, "Unknown action '#{action}'"
end
end
end end
end end
end end
...@@ -1294,6 +1294,42 @@ module Gitlab ...@@ -1294,6 +1294,42 @@ module Gitlab
success || gitlab_projects_error success || gitlab_projects_error
end 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)
OperationService.new(user, self).with_branch(
branch_name,
start_branch_name: start_branch_name,
start_repository: start_repository
) do |start_commit|
index = Gitlab::Git::Index.new(self)
parents = []
if start_commit
index.read_tree(start_commit.rugged_commit.tree)
parents = [start_commit.sha]
end
actions.each { |opts| index.apply(opts.delete(:action), opts) }
committer = user_to_committer(user)
author = Gitlab::Git.committer_hash(email: author_email, name: author_name) || committer
options = {
tree: index.write_tree,
message: message,
parents: parents,
author: author,
committer: committer
}
create_commit(options)
end
end
# rubocop:enable Metrics/ParameterLists
def gitaly_repository def gitaly_repository
Gitlab::GitalyClient::Util.repository(@storage, @relative_path, @gl_repository) Gitlab::GitalyClient::Util.repository(@storage, @relative_path, @gl_repository)
end end
......
...@@ -582,38 +582,6 @@ describe Repository do ...@@ -582,38 +582,6 @@ describe Repository do
end end
end end
describe '#get_committer_and_author' do
it 'returns the committer and author data' do
options = repository.get_committer_and_author(user)
expect(options[:committer][:email]).to eq(user.email)
expect(options[:author][:email]).to eq(user.email)
end
context 'when the email/name are given' do
it 'returns an object containing the email/name' do
options = repository.get_committer_and_author(user, email: author_email, name: author_name)
expect(options[:author][:email]).to eq(author_email)
expect(options[:author][:name]).to eq(author_name)
end
end
context 'when the email is given but the name is not' do
it 'returns the committer as the author' do
options = repository.get_committer_and_author(user, email: author_email)
expect(options[:author][:email]).to eq(user.email)
expect(options[:author][:name]).to eq(user.name)
end
end
context 'when the name is given but the email is not' do
it 'returns nil' do
options = repository.get_committer_and_author(user, name: author_name)
expect(options[:author][:email]).to eq(user.email)
expect(options[:author][:name]).to eq(user.name)
end
end
end
describe "search_files_by_content" do describe "search_files_by_content" do
let(:results) { repository.search_files_by_content('feature', 'master') } let(:results) { repository.search_files_by_content('feature', 'master') }
subject { results } subject { results }
...@@ -1112,16 +1080,16 @@ describe Repository do ...@@ -1112,16 +1080,16 @@ describe Repository do
allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([true, '']) allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([true, ''])
end end
it 'expires branch cache' do subject do
expect(repository).not_to receive(:expire_exists_cache) Gitlab::Git::OperationService.new(git_user, repository.raw_repository).with_branch('new-feature') do
expect(repository).not_to receive(:expire_root_ref_cache)
expect(repository).not_to receive(:expire_emptiness_caches)
expect(repository).to receive(:expire_branches_cache)
repository.with_branch(user, 'new-feature') do
new_rev new_rev
end end
end end
it 'returns branch_created as true' do
expect(subject).not_to be_repo_created
expect(subject).to be_branch_created
end
end end
context 'when repository is empty' do context 'when repository is empty' do
......
...@@ -41,7 +41,7 @@ describe Files::MultiService do ...@@ -41,7 +41,7 @@ describe Files::MultiService do
describe '#execute' do describe '#execute' do
context 'with a valid action' do context 'with a valid action' do
it 'returns a hash with the :success status ' do it 'returns a hash with the :success status' do
results = subject.execute results = subject.execute
expect(results[:status]).to eq(:success) expect(results[:status]).to eq(:success)
...@@ -51,7 +51,7 @@ describe Files::MultiService do ...@@ -51,7 +51,7 @@ describe Files::MultiService do
context 'with an invalid action' do context 'with an invalid action' do
let(:action) { 'rename' } let(:action) { 'rename' }
it 'returns a hash with the :error status ' do it 'returns a hash with the :error status' do
results = subject.execute results = subject.execute
expect(results[:status]).to eq(:error) expect(results[:status]).to eq(:error)
......
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