Commit 3bd599db authored by Marin Jankovski's avatar Marin Jankovski

Merge branch 'ce-to-ee-2018-02-19' into 'master'

CE upstream - 2018-02-19 12:23 UTC

Closes #4972 and #4960

See merge request gitlab-org/gitlab-ee!4596
parents e7e4f30d 7247b764
...@@ -417,6 +417,10 @@ class Commit ...@@ -417,6 +417,10 @@ class Commit
!!(title =~ WIP_REGEX) !!(title =~ WIP_REGEX)
end end
def merged_merge_request?(user)
!!merged_merge_request(user)
end
private private
def commit_reference(from, referable_commit_id, full: false) def commit_reference(from, referable_commit_id, full: false)
...@@ -445,10 +449,6 @@ class Commit ...@@ -445,10 +449,6 @@ class Commit
changes changes
end end
def merged_merge_request?(user)
!!merged_merge_request(user)
end
def merged_merge_request_no_cache(user) def merged_merge_request_no_cache(user)
MergeRequestsFinder.new(user, project_id: project.id).find_by(merge_commit_sha: id) if merge_commit? MergeRequestsFinder.new(user, project_id: project.id).find_by(merge_commit_sha: id) if merge_commit?
end end
......
...@@ -61,6 +61,8 @@ class User < ActiveRecord::Base ...@@ -61,6 +61,8 @@ class User < ActiveRecord::Base
# Override Devise::Models::Trackable#update_tracked_fields! # Override Devise::Models::Trackable#update_tracked_fields!
# to limit database writes to at most once every hour # to limit database writes to at most once every hour
def update_tracked_fields!(request) def update_tracked_fields!(request)
return if Gitlab::Database.read_only?
update_tracked_fields(request) update_tracked_fields(request)
lease = Gitlab::ExclusiveLease.new("user_update_tracked_fields:#{id}", timeout: 1.hour.to_i) lease = Gitlab::ExclusiveLease.new("user_update_tracked_fields:#{id}", timeout: 1.hour.to_i)
......
...@@ -23,27 +23,25 @@ class ProcessCommitWorker ...@@ -23,27 +23,25 @@ class ProcessCommitWorker
return unless user return unless user
commit = build_commit(project, commit_hash) commit = build_commit(project, commit_hash)
author = commit.author || user author = commit.author || user
process_commit_message(project, commit, user, author, default) process_commit_message(project, commit, user, author, default)
update_issue_metrics(commit, author) update_issue_metrics(commit, author)
end end
def process_commit_message(project, commit, user, author, default = false) def process_commit_message(project, commit, user, author, default = false)
closed_issues = default ? commit.closes_issues(user) : [] # this is a GitLab generated commit message, ignore it.
return if commit.merged_merge_request?(user)
unless closed_issues.empty? closed_issues = default ? commit.closes_issues(user) : []
close_issues(project, user, author, commit, closed_issues)
end
close_issues(project, user, author, commit, closed_issues) if closed_issues.any?
commit.create_cross_references!(author, closed_issues) commit.create_cross_references!(author, closed_issues)
end end
def close_issues(project, user, author, commit, issues) def close_issues(project, user, author, commit, issues)
# We don't want to run permission related queries for every single issue, # We don't want to run permission related queries for every single issue,
# therefor we use IssueCollection here and skip the authorization check in # therefore we use IssueCollection here and skip the authorization check in
# Issues::CloseService#execute. # Issues::CloseService#execute.
IssueCollection.new(issues).updatable_by_user(user).each do |issue| IssueCollection.new(issues).updatable_by_user(user).each do |issue|
Issues::CloseService.new(project, author) Issues::CloseService.new(project, author)
......
---
title: Fix duplicate system notes when merging a merge request.
merge_request: 17035
author:
type: fixed
---
title: Fix squash not working when diff contained non-ASCII data
merge_request:
author:
type: fixed
---
title: Don't attempt to update user tracked fields if database is in read-only
merge_request:
author:
type: fixed
...@@ -508,7 +508,7 @@ module Gitlab ...@@ -508,7 +508,7 @@ module Gitlab
@committed_date = Time.at(commit.committer.date.seconds).utc @committed_date = Time.at(commit.committer.date.seconds).utc
@committer_name = commit.committer.name.dup @committer_name = commit.committer.name.dup
@committer_email = commit.committer.email.dup @committer_email = commit.committer.email.dup
@parent_ids = commit.parent_ids @parent_ids = Array(commit.parent_ids)
end end
def serialize_keys def serialize_keys
......
...@@ -2195,6 +2195,7 @@ module Gitlab ...@@ -2195,6 +2195,7 @@ module Gitlab
# Apply diff of the `diff_range` to the worktree # Apply diff of the `diff_range` to the worktree
diff = run_git!(%W(diff --binary #{diff_range})) diff = run_git!(%W(diff --binary #{diff_range}))
run_git!(%w(apply --index), chdir: squash_path, env: env) do |stdin| run_git!(%w(apply --index), chdir: squash_path, env: env) do |stdin|
stdin.binmode
stdin.write(diff) stdin.write(diff)
end end
......
# coding: utf-8
require "spec_helper" require "spec_helper"
describe Gitlab::Git::Repository, seed_helper: true do describe Gitlab::Git::Repository, seed_helper: true do
...@@ -2221,6 +2222,17 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -2221,6 +2222,17 @@ describe Gitlab::Git::Repository, seed_helper: true do
subject subject
end end
end end
context 'with an ASCII-8BIT diff', :skip_gitaly_mock do
let(:diff) { "diff --git a/README.md b/README.md\nindex faaf198..43c5edf 100644\n--- a/README.md\n+++ b/README.md\n@@ -1,4 +1,4 @@\n-testme\n+✓ testme\n ======\n \n Sample repo for testing gitlab features\n" }
it 'applies a ASCII-8BIT diff' do
allow(repository).to receive(:run_git!).and_call_original
allow(repository).to receive(:run_git!).with(%W(diff --binary #{start_sha}...#{end_sha})).and_return(diff.force_encoding('ASCII-8BIT'))
expect(subject.length).to eq(40)
end
end
end end
end end
......
...@@ -524,6 +524,14 @@ describe User do ...@@ -524,6 +524,14 @@ describe User do
user2.update_tracked_fields!(request) user2.update_tracked_fields!(request)
end.to change { user2.reload.current_sign_in_at } end.to change { user2.reload.current_sign_in_at }
end end
it 'does not write if the DB is in read-only mode' do
expect(Gitlab::Database).to receive(:read_only?).and_return(true)
expect do
user.update_tracked_fields!(request)
end.not_to change { user.reload.current_sign_in_at }
end
end end
shared_context 'user keys' do shared_context 'user keys' do
......
...@@ -20,6 +20,32 @@ describe ProcessCommitWorker do ...@@ -20,6 +20,32 @@ describe ProcessCommitWorker do
worker.perform(project.id, -1, commit.to_hash) worker.perform(project.id, -1, commit.to_hash)
end end
context 'when commit is a merge request merge commit' do
let(:merge_request) do
create(:merge_request,
description: "Closes #{issue.to_reference}",
source_branch: 'feature-merged',
target_branch: 'master',
source_project: project)
end
let(:commit) do
project.repository.create_branch('feature-merged', 'feature')
sha = project.repository.merge(user,
merge_request.diff_head_sha,
merge_request,
"Closes #{issue.to_reference}")
project.repository.commit(sha)
end
it 'it does not close any issues from the commit message' do
expect(worker).not_to receive(:close_issues)
worker.perform(project.id, user.id, commit.to_hash)
end
end
it 'processes the commit message' do it 'processes the commit message' do
expect(worker).to receive(:process_commit_message).and_call_original expect(worker).to receive(:process_commit_message).and_call_original
...@@ -48,11 +74,9 @@ describe ProcessCommitWorker do ...@@ -48,11 +74,9 @@ describe ProcessCommitWorker do
describe '#process_commit_message' do describe '#process_commit_message' do
context 'when pushing to the default branch' do context 'when pushing to the default branch' do
it 'closes issues that should be closed per the commit message' do it 'closes issues that should be closed per the commit message' do
allow(commit).to receive(:safe_message) allow(commit).to receive(:safe_message).and_return("Closes #{issue.to_reference}")
.and_return("Closes #{issue.to_reference}")
expect(worker).to receive(:close_issues) expect(worker).to receive(:close_issues).with(project, user, user, commit, [issue])
.with(project, user, user, commit, [issue])
worker.process_commit_message(project, commit, user, user, true) worker.process_commit_message(project, commit, user, user, true)
end end
...@@ -60,8 +84,7 @@ describe ProcessCommitWorker do ...@@ -60,8 +84,7 @@ describe ProcessCommitWorker do
context 'when pushing to a non-default branch' do context 'when pushing to a non-default branch' do
it 'does not close any issues' do it 'does not close any issues' do
allow(commit).to receive(:safe_message) allow(commit).to receive(:safe_message).and_return("Closes #{issue.to_reference}")
.and_return("Closes #{issue.to_reference}")
expect(worker).not_to receive(:close_issues) expect(worker).not_to receive(:close_issues)
...@@ -102,8 +125,7 @@ describe ProcessCommitWorker do ...@@ -102,8 +125,7 @@ describe ProcessCommitWorker do
describe '#update_issue_metrics' do describe '#update_issue_metrics' do
it 'updates any existing issue metrics' do it 'updates any existing issue metrics' do
allow(commit).to receive(:safe_message) allow(commit).to receive(:safe_message).and_return("Closes #{issue.to_reference}")
.and_return("Closes #{issue.to_reference}")
worker.update_issue_metrics(commit, user) worker.update_issue_metrics(commit, user)
...@@ -113,10 +135,10 @@ describe ProcessCommitWorker do ...@@ -113,10 +135,10 @@ describe ProcessCommitWorker do
end end
it "doesn't execute any queries with false conditions" do it "doesn't execute any queries with false conditions" do
allow(commit).to receive(:safe_message) allow(commit).to receive(:safe_message).and_return("Lorem Ipsum")
.and_return("Lorem Ipsum")
expect { worker.update_issue_metrics(commit, user) }.not_to make_queries_matching(/WHERE (?:1=0|0=1)/) expect { worker.update_issue_metrics(commit, user) }
.not_to make_queries_matching(/WHERE (?:1=0|0=1)/)
end end
end end
...@@ -128,8 +150,9 @@ describe ProcessCommitWorker do ...@@ -128,8 +150,9 @@ describe ProcessCommitWorker do
end end
it 'parses date strings into Time instances' do it 'parses date strings into Time instances' do
commit = worker commit = worker.build_commit(project,
.build_commit(project, id: '123', authored_date: Time.now.to_s) id: '123',
authored_date: Time.now.to_s)
expect(commit.authored_date).to be_an_instance_of(Time) expect(commit.authored_date).to be_an_instance_of(Time)
end end
......
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