comparison app/models/changeset.rb @ 1115:433d4f72a19b redmine-2.2

Update to Redmine SVN revision 11137 on 2.2-stable branch
author Chris Cannam
date Mon, 07 Jan 2013 12:01:42 +0000
parents 5f33065ddc4b
children bb32da3bea34 622f24f53b42 261b3d9a4903
comparison
equal deleted inserted replaced
929:5f33065ddc4b 1115:433d4f72a19b
1 # Redmine - project management software 1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang 2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 # 3 #
4 # This program is free software; you can redistribute it and/or 4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License 5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2 6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version. 7 # of the License, or (at your option) any later version.
18 require 'iconv' 18 require 'iconv'
19 19
20 class Changeset < ActiveRecord::Base 20 class Changeset < ActiveRecord::Base
21 belongs_to :repository 21 belongs_to :repository
22 belongs_to :user 22 belongs_to :user
23 has_many :changes, :dependent => :delete_all 23 has_many :filechanges, :class_name => 'Change', :dependent => :delete_all
24 has_and_belongs_to_many :issues 24 has_and_belongs_to_many :issues
25 has_and_belongs_to_many :parents, 25 has_and_belongs_to_many :parents,
26 :class_name => "Changeset", 26 :class_name => "Changeset",
27 :join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}", 27 :join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}",
28 :association_foreign_key => 'parent_id', :foreign_key => 'changeset_id' 28 :association_foreign_key => 'parent_id', :foreign_key => 'changeset_id'
29 has_and_belongs_to_many :children, 29 has_and_belongs_to_many :children,
30 :class_name => "Changeset", 30 :class_name => "Changeset",
31 :join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}", 31 :join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}",
32 :association_foreign_key => 'changeset_id', :foreign_key => 'parent_id' 32 :association_foreign_key => 'changeset_id', :foreign_key => 'parent_id'
33 33
34 acts_as_event :title => Proc.new {|o| "#{l(:label_revision)} #{o.format_identifier}" + (o.short_comments.blank? ? '' : (': ' + o.short_comments))}, 34 acts_as_event :title => Proc.new {|o| o.title},
35 :description => :long_comments, 35 :description => :long_comments,
36 :datetime => :committed_on, 36 :datetime => :committed_on,
37 :url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :rev => o.identifier}} 37 :url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :repository_id => o.repository.identifier_param, :rev => o.identifier}}
38 38
39 acts_as_searchable :columns => 'comments', 39 acts_as_searchable :columns => 'comments',
40 :include => {:repository => :project}, 40 :include => {:repository => :project},
41 :project_key => "#{Repository.table_name}.project_id", 41 :project_key => "#{Repository.table_name}.project_id",
42 :date_column => 'committed_on' 42 :date_column => 'committed_on'
47 47
48 validates_presence_of :repository_id, :revision, :committed_on, :commit_date 48 validates_presence_of :repository_id, :revision, :committed_on, :commit_date
49 validates_uniqueness_of :revision, :scope => :repository_id 49 validates_uniqueness_of :revision, :scope => :repository_id
50 validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true 50 validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
51 51
52 named_scope :visible, lambda {|*args| { :include => {:repository => :project}, 52 scope :visible,
53 lambda {|*args| { :include => {:repository => :project},
53 :conditions => Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args) } } 54 :conditions => Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args) } }
54 55
55 after_create :scan_for_issues 56 after_create :scan_for_issues
56 before_create :before_create_cs 57 before_create :before_create_cs
57 58
155 tag = if scmid? 156 tag = if scmid?
156 "commit:#{scmid}" 157 "commit:#{scmid}"
157 else 158 else
158 "r#{revision}" 159 "r#{revision}"
159 end 160 end
161 if repository && repository.identifier.present?
162 tag = "#{repository.identifier}|#{tag}"
163 end
160 if ref_project && project && ref_project != project 164 if ref_project && project && ref_project != project
161 tag = "#{project.identifier}:#{tag}" 165 tag = "#{project.identifier}:#{tag}"
162 end 166 end
163 tag 167 tag
168 end
169
170 # Returns the title used for the changeset in the activity/search results
171 def title
172 repo = (repository && repository.identifier.present?) ? " (#{repository.identifier})" : ''
173 comm = short_comments.blank? ? '' : (': ' + short_comments)
174 "#{l(:label_revision)} #{format_identifier}#{repo}#{comm}"
164 end 175 end
165 176
166 # Returns the previous changeset 177 # Returns the previous changeset
167 def previous 178 def previous
168 @previous ||= Changeset.find(:first, 179 @previous ||= Changeset.where(["id < ? AND repository_id = ?", id, repository_id]).order('id DESC').first
169 :conditions => ['id < ? AND repository_id = ?',
170 self.id, self.repository_id],
171 :order => 'id DESC')
172 end 180 end
173 181
174 # Returns the next changeset 182 # Returns the next changeset
175 def next 183 def next
176 @next ||= Changeset.find(:first, 184 @next ||= Changeset.where(["id > ? AND repository_id = ?", id, repository_id]).order('id ASC').first
177 :conditions => ['id > ? AND repository_id = ?',
178 self.id, self.repository_id],
179 :order => 'id ASC')
180 end 185 end
181 186
182 # Creates a new Change from it's common parameters 187 # Creates a new Change from it's common parameters
183 def create_change(change) 188 def create_change(change)
184 Change.create(:changeset => self, 189 Change.create(:changeset => self,
186 :path => change[:path], 191 :path => change[:path],
187 :from_path => change[:from_path], 192 :from_path => change[:from_path],
188 :from_revision => change[:from_revision]) 193 :from_revision => change[:from_revision])
189 end 194 end
190 195
191 private
192
193 # Finds an issue that can be referenced by the commit message 196 # Finds an issue that can be referenced by the commit message
194 # i.e. an issue that belong to the repository project, a subproject or a parent project
195 def find_referenced_issue_by_id(id) 197 def find_referenced_issue_by_id(id)
196 return nil if id.blank? 198 return nil if id.blank?
197 issue = Issue.find_by_id(id.to_i, :include => :project) 199 issue = Issue.find_by_id(id.to_i, :include => :project)
198 if issue 200 if Setting.commit_cross_project_ref?
201 # all issues can be referenced/fixed
202 elsif issue
203 # issue that belong to the repository project, a subproject or a parent project only
199 unless issue.project && 204 unless issue.project &&
200 (project == issue.project || project.is_ancestor_of?(issue.project) || 205 (project == issue.project || project.is_ancestor_of?(issue.project) ||
201 project.is_descendant_of?(issue.project)) 206 project.is_descendant_of?(issue.project))
202 issue = nil 207 issue = nil
203 end 208 end
204 end 209 end
205 issue 210 issue
206 end 211 end
212
213 private
207 214
208 def fix_issue(issue) 215 def fix_issue(issue)
209 status = IssueStatus.find_by_id(Setting.commit_fix_status_id.to_i) 216 status = IssueStatus.find_by_id(Setting.commit_fix_status_id.to_i)
210 if status.nil? 217 if status.nil?
211 logger.warn("No status matches commit_fix_status_id setting (#{Setting.commit_fix_status_id})") if logger 218 logger.warn("No status matches commit_fix_status_id setting (#{Setting.commit_fix_status_id})") if logger