summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2014-10-05 12:10:33 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2014-10-05 12:10:33 +0000
commita5675463352040ae8e63b0ba6c20a27dbfefc0d3 (patch)
tree5c5d97326aa0a81d96edee9563e2e90cf70d4a6d
parent8b678837a353747f6f4fcce343c603daf1e07fbe (diff)
downloadredmine-a5675463352040ae8e63b0ba6c20a27dbfefc0d3.tar.gz
redmine-a5675463352040ae8e63b0ba6c20a27dbfefc0d3.zip
Don't link multiple changesets from the same commit multiple times (#17931).
git-svn-id: http://svn.redmine.org/redmine/trunk@13427 e93f8b46-1217-0410-a6f0-8f06a7374b81
-rw-r--r--app/models/changeset.rb8
-rw-r--r--app/models/repository.rb12
-rw-r--r--test/unit/changeset_test.rb11
3 files changed, 30 insertions, 1 deletions
diff --git a/app/models/changeset.rb b/app/models/changeset.rb
index fea170ddc..cf58c6e07 100644
--- a/app/models/changeset.rb
+++ b/app/models/changeset.rb
@@ -130,7 +130,7 @@ class Changeset < ActiveRecord::Base
refs.scan(/#(\d+)(\s+@#{TIMELOG_RE})?/).each do |m|
issue, hours = find_referenced_issue_by_id(m[0].to_i), m[2]
- if issue
+ if issue && !issue_linked_to_same_commit?(issue)
referenced_issues << issue
# Don't update issues or log time when importing old commits
unless repository.created_on && committed_on && committed_on < repository.created_on
@@ -214,6 +214,12 @@ class Changeset < ActiveRecord::Base
private
+ # Returns true if the issue is already linked to the same commit
+ # from a different repository
+ def issue_linked_to_same_commit?(issue)
+ repository.same_commits_in_scope(issue.changesets, self).any?
+ end
+
# Updates the +issue+ according to +action+
def fix_issue(issue, action)
# the issue may have been updated by the closure of another one (eg. duplicate)
diff --git a/app/models/repository.rb b/app/models/repository.rb
index fe08e95ce..25b0e1da8 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -442,6 +442,18 @@ class Repository < ActiveRecord::Base
end
end
+ # Returns a scope of changesets that come from the same commit as the given changeset
+ # in different repositories that point to the same backend
+ def same_commits_in_scope(scope, changeset)
+ scope = scope.joins(:repository).where(:repositories => {:url => url, :root_url => root_url, :type => type})
+ if changeset.scmid.present?
+ scope = scope.where(:scmid => changeset.scmid)
+ else
+ scope = scope.where(:revision => changeset.revision)
+ end
+ scope
+ end
+
protected
def check_default
diff --git a/test/unit/changeset_test.rb b/test/unit/changeset_test.rb
index da78417b1..0467d59a1 100644
--- a/test/unit/changeset_test.rb
+++ b/test/unit/changeset_test.rb
@@ -297,6 +297,17 @@ class ChangesetTest < ActiveSupport::TestCase
assert_equal 0, issue.done_ratio
end
+ def test_2_repositories_with_same_backend_should_not_link_issue_multiple_times
+ Setting.commit_ref_keywords = '*'
+ r1 = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///svn1')
+ r2 = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn2', :url => 'file:///svn1')
+ now = Time.now
+ assert_difference 'Issue.find(1).changesets.count' do
+ c1 = Changeset.create!(:repository => r1, :committed_on => now, :comments => 'Fixes #1', :revision => '12345')
+ c1 = Changeset.create!(:repository => r2, :committed_on => now, :comments => 'Fixes #1', :revision => '12345')
+ end
+ end
+
def test_text_tag_revision
c = Changeset.new(:revision => '520')
assert_equal 'r520', c.text_tag