summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Vosmaer <jacob@gitlab.com>2016-09-07 16:26:06 +0200
committerJacob Vosmaer <jacob@gitlab.com>2016-09-07 16:26:06 +0200
commita75026915863280c78fe73211e423bf6f4ce11c4 (patch)
tree879b20ed565aff12499b1a4c6ab0692e1f751d33
parenta83c5ff48f74c718bd4d0f9b5746502e2ebaff27 (diff)
downloadgitlab-ce-a75026915863280c78fe73211e423bf6f4ce11c4.tar.gz
Allow adding multiple commits in commit_with_hooks
-rw-r--r--app/models/repository.rb6
-rw-r--r--spec/models/repository_spec.rb19
2 files changed, 24 insertions, 1 deletions
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 414b82516bc..83605982933 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -1040,7 +1040,11 @@ class Repository
raise CommitError.new('Failed to create commit')
end
- oldrev = rugged.lookup(newrev).parent_ids.first || Gitlab::Git::BLANK_SHA
+ if rugged.lookup(newrev).parent_ids.empty? || target_branch.nil?
+ oldrev = Gitlab::Git::BLANK_SHA
+ else
+ oldrev = rugged.merge_base(newrev, target_branch.target.sha)
+ end
GitHooksService.new.execute(current_user, path_to_repo, oldrev, newrev, ref) do
update_ref!(ref, newrev, oldrev)
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index afc7dc5db81..17eecf6bbd6 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -473,6 +473,25 @@ describe Repository, models: true do
end
end
+ context 'when the update adds more than one commit' do
+ it 'runs without errors' do
+ old_rev = '33f3729a45c02fc67d00adb1b8bca394b0e761d9' # ancestor of new_rev by more than one commit
+ branch = 'feature-ff-target'
+ repository.add_branch(user, branch, old_rev)
+
+ expect { repository.commit_with_hooks(user, branch) { new_rev } }.not_to raise_error
+ end
+ end
+
+ context 'when the update would remove commits from the target branch' do
+ it 'raises an exception' do
+ # We use the fact that 'master' has diverged from 'feature' (new_rev):
+ # updating 'master' to new_rev would make us lose commits, which should
+ # not happen.
+ expect { repository.commit_with_hooks(user, 'master') { new_rev } }.to raise_error(Repository::CommitError)
+ end
+ end
+
context 'when pre hooks failed' do
it 'gets an error' do
allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([false, ''])