diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index c5b819f47..09ce9f2db 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -108,7 +108,7 @@ class IssuesController < ApplicationController @journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC") @journals.each_with_index {|j,i| j.indice = i+1} @journals.reverse! if User.current.wants_comments_in_reverse_order? - @changesets = @issue.changesets + @changesets = @issue.changesets.visible.all @changesets.reverse! if User.current.wants_comments_in_reverse_order? @allowed_statuses = @issue.new_statuses_allowed_to(User.current) @edit_allowed = User.current.allowed_to?(:edit_issues, @project) diff --git a/app/models/changeset.rb b/app/models/changeset.rb index 336632afd..f7145631e 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -41,6 +41,9 @@ class Changeset < ActiveRecord::Base validates_uniqueness_of :revision, :scope => :repository_id validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true + named_scope :visible, lambda {|*args| { :include => {:repository => :project}, + :conditions => Project.allowed_to_condition(args.first || User.current, :view_changesets) } } + def revision=(r) write_attribute :revision, (r.nil? ? nil : r.to_s) end @@ -90,13 +93,13 @@ class Changeset < ActiveRecord::Base # find any issue ID in the comments target_issue_ids = [] comments.scan(%r{([\s\(\[,-]|^)#(\d+)(?=[[:punct:]]|\s|<|$)}).each { |m| target_issue_ids << m[1] } - referenced_issues += repository.project.issues.find_all_by_id(target_issue_ids) + referenced_issues += find_referenced_issues_by_id(target_issue_ids) end comments.scan(Regexp.new("(#{kw_regexp})[\s:]+(([\s,;&]*#?\\d+)+)", Regexp::IGNORECASE)).each do |match| action = match[0] target_issue_ids = match[1].scan(/\d+/) - target_issues = repository.project.issues.find_all_by_id(target_issue_ids) + target_issues = find_referenced_issues_by_id(target_issue_ids) if fix_status && fix_keywords.include?(action.downcase) # update status of issues logger.debug "Issues fixed by changeset #{self.revision}: #{issue_ids.join(', ')}." if logger && logger.debug? @@ -148,6 +151,14 @@ class Changeset < ActiveRecord::Base private + # Finds issues that can be referenced by the commit message + # i.e. issues that belong to the repository project, a subproject or a parent project + def find_referenced_issues_by_id(ids) + Issue.find_all_by_id(ids, :include => :project).select {|issue| + project == issue.project || project.is_ancestor_of?(issue.project) || project.is_descendant_of?(issue.project) + } + end + def split_comments comments =~ /\A(.+?)\r?\n(.*)$/m @short_comments = $1 || comments diff --git a/app/views/issues/show.rhtml b/app/views/issues/show.rhtml index 90a9d963d..6c83c44fb 100644 --- a/app/views/issues/show.rhtml +++ b/app/views/issues/show.rhtml @@ -73,7 +73,7 @@ -<% if @changesets.any? && User.current.allowed_to?(:view_changesets, @project) %> +<% if @changesets.any? %>

<%=l(:label_associated_revisions)%>

<%= render :partial => 'changesets', :locals => { :changesets => @changesets} %> diff --git a/test/unit/changeset_test.rb b/test/unit/changeset_test.rb index 02736a9a0..8d57c43ab 100644 --- a/test/unit/changeset_test.rb +++ b/test/unit/changeset_test.rb @@ -74,6 +74,29 @@ class ChangesetTest < ActiveSupport::TestCase assert_equal [1,2,3], c.issue_ids.sort end + + def test_commit_referencing_a_subproject_issue + c = Changeset.new(:repository => Project.find(1).repository, + :committed_on => Time.now, + :comments => 'refs #5, a subproject issue') + c.scan_comment_for_issue_ids + + assert_equal [5], c.issue_ids.sort + assert c.issues.first.project != c.project + end + + def test_commit_referencing_a_parent_project_issue + # repository of child project + r = Repository::Subversion.create!(:project => Project.find(3), :url => 'svn://localhost/test') + + c = Changeset.new(:repository => r, + :committed_on => Time.now, + :comments => 'refs #2, an issue of a parent project') + c.scan_comment_for_issue_ids + + assert_equal [2], c.issue_ids.sort + assert c.issues.first.project != c.project + end def test_previous changeset = Changeset.find_by_revision('3')