]> source.dussan.org Git - redmine.git/commitdiff
Don't link multiple changesets from the same commit multiple times (#17931).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 5 Oct 2014 12:10:33 +0000 (12:10 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 5 Oct 2014 12:10:33 +0000 (12:10 +0000)
git-svn-id: http://svn.redmine.org/redmine/trunk@13427 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/models/changeset.rb
app/models/repository.rb
test/unit/changeset_test.rb

index fea170ddcce2ea08da37693adf07b212e2b9a129..cf58c6e073c593b06471a0bd598433cb5bd2dda2 100644 (file)
@@ -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)
index fe08e95ce1906155ee9c2a8e47fc275eb7748b5b..25b0e1da8b4783f6e099508f35dd6dbdc32e5587 100644 (file)
@@ -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
index da78417b186d209a0112393134abb6f9c7436efa..0467d59a109764c9bb678c7f11b1a3326e02b66e 100644 (file)
@@ -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