Commit bb9d3059 authored by Lin Jen-Shin's avatar Lin Jen-Shin

Pass source_commit so that we save a few lookups

parent 5a115671
...@@ -849,15 +849,12 @@ class Repository ...@@ -849,15 +849,12 @@ class Repository
GitOperationService.new(user, self).with_branch( GitOperationService.new(user, self).with_branch(
branch_name, branch_name,
source_branch_name: source_branch_name, source_branch_name: source_branch_name,
source_project: source_project) do source_project: source_project) do |source_commit|
index = rugged.index index = rugged.index
branch_commit = source_project.repository.find_branch(
source_branch_name || branch_name)
parents = if branch_commit parents = if source_commit
last_commit = branch_commit.dereferenced_target index.read_tree(source_commit.raw_commit.tree)
index.read_tree(last_commit.raw_commit.tree) [source_commit.sha]
[last_commit.sha]
else else
[] []
end end
...@@ -904,17 +901,17 @@ class Repository ...@@ -904,17 +901,17 @@ class Repository
end end
def merge(user, merge_request, options = {}) def merge(user, merge_request, options = {})
our_commit = rugged.branches[merge_request.target_branch].target GitOperationService.new(user, self).with_branch(
their_commit = rugged.lookup(merge_request.diff_head_sha) merge_request.target_branch) do |source_commit|
our_commit = source_commit.raw_commit
their_commit = rugged.lookup(merge_request.diff_head_sha)
raise "Invalid merge target" if our_commit.nil? raise 'Invalid merge target' unless our_commit
raise "Invalid merge source" if their_commit.nil? raise 'Invalid merge source' unless their_commit
merge_index = rugged.merge_commits(our_commit, their_commit) merge_index = rugged.merge_commits(our_commit, their_commit)
return false if merge_index.conflicts? break if merge_index.conflicts?
GitOperationService.new(user, self).with_branch(
merge_request.target_branch) do
actual_options = options.merge( actual_options = options.merge(
parents: [our_commit, their_commit], parents: [our_commit, their_commit],
tree: merge_index.write_tree(rugged), tree: merge_index.write_tree(rugged),
...@@ -924,6 +921,8 @@ class Repository ...@@ -924,6 +921,8 @@ class Repository
merge_request.update(in_progress_merge_commit_sha: commit_id) merge_request.update(in_progress_merge_commit_sha: commit_id)
commit_id commit_id
end end
rescue Repository::CommitError # when merge_index.conflicts?
false
end end
def revert( def revert(
...@@ -936,10 +935,8 @@ class Repository ...@@ -936,10 +935,8 @@ class Repository
GitOperationService.new(user, self).with_branch( GitOperationService.new(user, self).with_branch(
branch_name, branch_name,
source_branch_name: source_branch_name, source_branch_name: source_branch_name,
source_project: source_project) do source_project: source_project) do |source_commit|
source_sha = source_project.repository.find_source_sha(
source_branch_name || branch_name)
committer = user_to_committer(user) committer = user_to_committer(user)
Rugged::Commit.create(rugged, Rugged::Commit.create(rugged,
...@@ -947,7 +944,7 @@ class Repository ...@@ -947,7 +944,7 @@ class Repository
author: committer, author: committer,
committer: committer, committer: committer,
tree: revert_tree_id, tree: revert_tree_id,
parents: [rugged.lookup(source_sha)]) parents: [source_commit.sha])
end end
end end
...@@ -961,10 +958,8 @@ class Repository ...@@ -961,10 +958,8 @@ class Repository
GitOperationService.new(user, self).with_branch( GitOperationService.new(user, self).with_branch(
branch_name, branch_name,
source_branch_name: source_branch_name, source_branch_name: source_branch_name,
source_project: source_project) do source_project: source_project) do |source_commit|
source_sha = source_project.repository.find_source_sha(
source_branch_name || branch_name)
committer = user_to_committer(user) committer = user_to_committer(user)
Rugged::Commit.create(rugged, Rugged::Commit.create(rugged,
...@@ -976,7 +971,7 @@ class Repository ...@@ -976,7 +971,7 @@ class Repository
}, },
committer: committer, committer: committer,
tree: cherry_pick_tree_id, tree: cherry_pick_tree_id,
parents: [rugged.lookup(source_sha)]) parents: [source_commit.sha])
end end
end end
...@@ -1145,16 +1140,6 @@ class Repository ...@@ -1145,16 +1140,6 @@ class Repository
end end
end end
protected
def find_source_sha(branch_name)
if branch_exists?(branch_name)
find_branch(branch_name).dereferenced_target.sha
else
Gitlab::Git::BLANK_SHA
end
end
private private
def git_action(index, action) def git_action(index, action)
......
...@@ -37,13 +37,16 @@ GitOperationService = Struct.new(:user, :repository) do ...@@ -37,13 +37,16 @@ GitOperationService = Struct.new(:user, :repository) do
check_with_branch_arguments!( check_with_branch_arguments!(
branch_name, source_branch_name, source_project) branch_name, source_branch_name, source_project)
update_branch_with_hooks(branch_name) do |ref| source_commit = source_project.repository.find_branch(
source_branch_name || branch_name).try(:dereferenced_target)
update_branch_with_hooks(branch_name) do
if repository.project == source_project if repository.project == source_project
yield(ref) yield(source_commit)
else else
repository.with_tmp_ref( repository.with_tmp_ref(
source_project.repository, source_branch_name) do source_project.repository, source_branch_name) do
yield(ref) yield(source_commit)
end end
end end
end end
...@@ -54,31 +57,29 @@ GitOperationService = Struct.new(:user, :repository) do ...@@ -54,31 +57,29 @@ GitOperationService = Struct.new(:user, :repository) do
def update_branch_with_hooks(branch_name) def update_branch_with_hooks(branch_name)
update_autocrlf_option update_autocrlf_option
ref = Gitlab::Git::BRANCH_REF_PREFIX + branch_name
oldrev = Gitlab::Git::BLANK_SHA
was_empty = repository.empty? was_empty = repository.empty?
# Make commit # Make commit
newrev = yield(ref) newrev = yield
unless newrev unless newrev
raise Repository::CommitError.new('Failed to create commit') raise Repository::CommitError.new('Failed to create commit')
end end
branch = repository.find_branch(branch_name) branch = repository.find_branch(branch_name)
oldrev = if repository.rugged.lookup(newrev).parent_ids.empty? || oldrev = if branch
branch.nil? # This could verify we're not losing commits
Gitlab::Git::BLANK_SHA repository.rugged.merge_base(newrev, branch.target)
else else
repository.rugged.merge_base( Gitlab::Git::BLANK_SHA
newrev, branch.dereferenced_target.sha)
end end
ref = Gitlab::Git::BRANCH_REF_PREFIX + branch_name
with_hooks_and_update_ref(ref, oldrev, newrev) do with_hooks_and_update_ref(ref, oldrev, newrev) do
# If repo was empty expire cache # If repo was empty expire cache
repository.after_create if was_empty repository.after_create if was_empty
repository.after_create_branch if was_empty || repository.after_create_branch if was_empty ||
oldrev == Gitlab::Git::BLANK_SHA Gitlab::Git.blank_ref?(oldrev)
end end
newrev newrev
......
...@@ -257,6 +257,24 @@ describe Repository, models: true do ...@@ -257,6 +257,24 @@ describe Repository, models: true do
expect(newdir.path).to eq('newdir') expect(newdir.path).to eq('newdir')
end end
context "when committing to another project" do
let(:forked_project) { create(:project) }
it "creates a fork and commit to the forked project" do
expect do
repository.commit_dir(user, 'newdir',
message: 'Create newdir', branch_name: 'patch',
source_branch_name: 'master', source_project: forked_project)
end.to change { repository.commits('master').count }.by(0)
expect(repository.branch_exists?('patch')).to be_truthy
expect(forked_project.repository.branch_exists?('patch')).to be_falsy
newdir = repository.tree('patch', 'newdir')
expect(newdir.path).to eq('newdir')
end
end
context "when an author is specified" do context "when an author is specified" do
it "uses the given email/name to set the commit's author" do it "uses the given email/name to set the commit's author" do
expect do expect do
...@@ -758,9 +776,9 @@ describe Repository, models: true do ...@@ -758,9 +776,9 @@ describe Repository, models: true do
end end
context 'when the update adds more than one commit' do context 'when the update adds more than one commit' do
it 'runs without errors' do let(:old_rev) { '33f3729a45c02fc67d00adb1b8bca394b0e761d9' }
old_rev = '33f3729a45c02fc67d00adb1b8bca394b0e761d9'
it 'runs without errors' do
# old_rev is an ancestor of new_rev # old_rev is an ancestor of new_rev
expect(repository.rugged.merge_base(old_rev, new_rev)).to eq(old_rev) expect(repository.rugged.merge_base(old_rev, new_rev)).to eq(old_rev)
...@@ -779,10 +797,10 @@ describe Repository, models: true do ...@@ -779,10 +797,10 @@ describe Repository, models: true do
end end
context 'when the update would remove commits from the target branch' do context 'when the update would remove commits from the target branch' do
it 'raises an exception' do let(:branch) { 'master' }
branch = 'master' let(:old_rev) { repository.find_branch(branch).dereferenced_target.sha }
old_rev = repository.find_branch(branch).dereferenced_target.sha
it 'raises an exception' do
# The 'master' branch is NOT an ancestor of new_rev. # The 'master' branch is NOT an ancestor of new_rev.
expect(repository.rugged.merge_base(old_rev, new_rev)).not_to eq(old_rev) expect(repository.rugged.merge_base(old_rev, new_rev)).not_to eq(old_rev)
......
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