##// END OF EJS Templates
Show view/annotate/download links on repositories/entries and repositories/annotate views (#2367)....
Jean-Philippe Lang -
r2165:3f80a89a69b2
parent child
Show More
@@ -1,325 +1,328
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 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.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require 'SVG/Graph/Bar'
18 require 'SVG/Graph/Bar'
19 require 'SVG/Graph/BarHorizontal'
19 require 'SVG/Graph/BarHorizontal'
20 require 'digest/sha1'
20 require 'digest/sha1'
21
21
22 class ChangesetNotFound < Exception; end
22 class ChangesetNotFound < Exception; end
23 class InvalidRevisionParam < Exception; end
23 class InvalidRevisionParam < Exception; end
24
24
25 class RepositoriesController < ApplicationController
25 class RepositoriesController < ApplicationController
26 menu_item :repository
26 menu_item :repository
27 before_filter :find_repository, :except => :edit
27 before_filter :find_repository, :except => :edit
28 before_filter :find_project, :only => :edit
28 before_filter :find_project, :only => :edit
29 before_filter :authorize
29 before_filter :authorize
30 accept_key_auth :revisions
30 accept_key_auth :revisions
31
31
32 rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed
32 rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed
33
33
34 def edit
34 def edit
35 @repository = @project.repository
35 @repository = @project.repository
36 if !@repository
36 if !@repository
37 @repository = Repository.factory(params[:repository_scm])
37 @repository = Repository.factory(params[:repository_scm])
38 @repository.project = @project if @repository
38 @repository.project = @project if @repository
39 end
39 end
40 if request.post? && @repository
40 if request.post? && @repository
41 @repository.attributes = params[:repository]
41 @repository.attributes = params[:repository]
42 @repository.save
42 @repository.save
43 end
43 end
44 render(:update) {|page| page.replace_html "tab-content-repository", :partial => 'projects/settings/repository'}
44 render(:update) {|page| page.replace_html "tab-content-repository", :partial => 'projects/settings/repository'}
45 end
45 end
46
46
47 def committers
47 def committers
48 @committers = @repository.committers
48 @committers = @repository.committers
49 @users = @project.users
49 @users = @project.users
50 additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id)
50 additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id)
51 @users += User.find_all_by_id(additional_user_ids) unless additional_user_ids.empty?
51 @users += User.find_all_by_id(additional_user_ids) unless additional_user_ids.empty?
52 @users.compact!
52 @users.compact!
53 @users.sort!
53 @users.sort!
54 if request.post? && params[:committers].is_a?(Hash)
54 if request.post? && params[:committers].is_a?(Hash)
55 # Build a hash with repository usernames as keys and corresponding user ids as values
55 # Build a hash with repository usernames as keys and corresponding user ids as values
56 @repository.committer_ids = params[:committers].values.inject({}) {|h, c| h[c.first] = c.last; h}
56 @repository.committer_ids = params[:committers].values.inject({}) {|h, c| h[c.first] = c.last; h}
57 flash[:notice] = l(:notice_successful_update)
57 flash[:notice] = l(:notice_successful_update)
58 redirect_to :action => 'committers', :id => @project
58 redirect_to :action => 'committers', :id => @project
59 end
59 end
60 end
60 end
61
61
62 def destroy
62 def destroy
63 @repository.destroy
63 @repository.destroy
64 redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'repository'
64 redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'repository'
65 end
65 end
66
66
67 def show
67 def show
68 # check if new revisions have been committed in the repository
68 # check if new revisions have been committed in the repository
69 @repository.fetch_changesets if Setting.autofetch_changesets?
69 @repository.fetch_changesets if Setting.autofetch_changesets?
70 # root entries
70 # root entries
71 @entries = @repository.entries('', @rev)
71 @entries = @repository.entries('', @rev)
72 # latest changesets
72 # latest changesets
73 @changesets = @repository.changesets.find(:all, :limit => 10, :order => "committed_on DESC")
73 @changesets = @repository.changesets.find(:all, :limit => 10, :order => "committed_on DESC")
74 show_error_not_found unless @entries || @changesets.any?
74 show_error_not_found unless @entries || @changesets.any?
75 end
75 end
76
76
77 def browse
77 def browse
78 @entries = @repository.entries(@path, @rev)
78 @entries = @repository.entries(@path, @rev)
79 if request.xhr?
79 if request.xhr?
80 @entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
80 @entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
81 else
81 else
82 show_error_not_found and return unless @entries
82 show_error_not_found and return unless @entries
83 @properties = @repository.properties(@path, @rev)
83 @properties = @repository.properties(@path, @rev)
84 render :action => 'browse'
84 render :action => 'browse'
85 end
85 end
86 end
86 end
87
87
88 def changes
88 def changes
89 @entry = @repository.entry(@path, @rev)
89 @entry = @repository.entry(@path, @rev)
90 show_error_not_found and return unless @entry
90 show_error_not_found and return unless @entry
91 @changesets = @repository.changesets_for_path(@path)
91 @changesets = @repository.changesets_for_path(@path)
92 @properties = @repository.properties(@path, @rev)
92 @properties = @repository.properties(@path, @rev)
93 end
93 end
94
94
95 def revisions
95 def revisions
96 @changeset_count = @repository.changesets.count
96 @changeset_count = @repository.changesets.count
97 @changeset_pages = Paginator.new self, @changeset_count,
97 @changeset_pages = Paginator.new self, @changeset_count,
98 per_page_option,
98 per_page_option,
99 params['page']
99 params['page']
100 @changesets = @repository.changesets.find(:all,
100 @changesets = @repository.changesets.find(:all,
101 :limit => @changeset_pages.items_per_page,
101 :limit => @changeset_pages.items_per_page,
102 :offset => @changeset_pages.current.offset,
102 :offset => @changeset_pages.current.offset,
103 :include => :user)
103 :include => :user)
104
104
105 respond_to do |format|
105 respond_to do |format|
106 format.html { render :layout => false if request.xhr? }
106 format.html { render :layout => false if request.xhr? }
107 format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") }
107 format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") }
108 end
108 end
109 end
109 end
110
110
111 def entry
111 def entry
112 @entry = @repository.entry(@path, @rev)
112 @entry = @repository.entry(@path, @rev)
113 show_error_not_found and return unless @entry
113 show_error_not_found and return unless @entry
114
114
115 # If the entry is a dir, show the browser
115 # If the entry is a dir, show the browser
116 browse and return if @entry.is_dir?
116 browse and return if @entry.is_dir?
117
117
118 @content = @repository.cat(@path, @rev)
118 @content = @repository.cat(@path, @rev)
119 show_error_not_found and return unless @content
119 show_error_not_found and return unless @content
120 if 'raw' == params[:format] || @content.is_binary_data?
120 if 'raw' == params[:format] || @content.is_binary_data?
121 # Force the download if it's a binary file
121 # Force the download if it's a binary file
122 send_data @content, :filename => @path.split('/').last
122 send_data @content, :filename => @path.split('/').last
123 else
123 else
124 # Prevent empty lines when displaying a file with Windows style eol
124 # Prevent empty lines when displaying a file with Windows style eol
125 @content.gsub!("\r\n", "\n")
125 @content.gsub!("\r\n", "\n")
126 end
126 end
127 end
127 end
128
128
129 def annotate
129 def annotate
130 @entry = @repository.entry(@path, @rev)
131 show_error_not_found and return unless @entry
132
130 @annotate = @repository.scm.annotate(@path, @rev)
133 @annotate = @repository.scm.annotate(@path, @rev)
131 render_error l(:error_scm_annotate) and return if @annotate.nil? || @annotate.empty?
134 render_error l(:error_scm_annotate) and return if @annotate.nil? || @annotate.empty?
132 end
135 end
133
136
134 def revision
137 def revision
135 @changeset = @repository.changesets.find_by_revision(@rev)
138 @changeset = @repository.changesets.find_by_revision(@rev)
136 raise ChangesetNotFound unless @changeset
139 raise ChangesetNotFound unless @changeset
137
140
138 respond_to do |format|
141 respond_to do |format|
139 format.html
142 format.html
140 format.js {render :layout => false}
143 format.js {render :layout => false}
141 end
144 end
142 rescue ChangesetNotFound
145 rescue ChangesetNotFound
143 show_error_not_found
146 show_error_not_found
144 end
147 end
145
148
146 def diff
149 def diff
147 if params[:format] == 'diff'
150 if params[:format] == 'diff'
148 @diff = @repository.diff(@path, @rev, @rev_to)
151 @diff = @repository.diff(@path, @rev, @rev_to)
149 show_error_not_found and return unless @diff
152 show_error_not_found and return unless @diff
150 filename = "changeset_r#{@rev}"
153 filename = "changeset_r#{@rev}"
151 filename << "_r#{@rev_to}" if @rev_to
154 filename << "_r#{@rev_to}" if @rev_to
152 send_data @diff.join, :filename => "#{filename}.diff",
155 send_data @diff.join, :filename => "#{filename}.diff",
153 :type => 'text/x-patch',
156 :type => 'text/x-patch',
154 :disposition => 'attachment'
157 :disposition => 'attachment'
155 else
158 else
156 @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
159 @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
157 @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
160 @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
158
161
159 # Save diff type as user preference
162 # Save diff type as user preference
160 if User.current.logged? && @diff_type != User.current.pref[:diff_type]
163 if User.current.logged? && @diff_type != User.current.pref[:diff_type]
161 User.current.pref[:diff_type] = @diff_type
164 User.current.pref[:diff_type] = @diff_type
162 User.current.preference.save
165 User.current.preference.save
163 end
166 end
164
167
165 @cache_key = "repositories/diff/#{@repository.id}/" + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}")
168 @cache_key = "repositories/diff/#{@repository.id}/" + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}")
166 unless read_fragment(@cache_key)
169 unless read_fragment(@cache_key)
167 @diff = @repository.diff(@path, @rev, @rev_to)
170 @diff = @repository.diff(@path, @rev, @rev_to)
168 show_error_not_found unless @diff
171 show_error_not_found unless @diff
169 end
172 end
170 end
173 end
171 end
174 end
172
175
173 def stats
176 def stats
174 end
177 end
175
178
176 def graph
179 def graph
177 data = nil
180 data = nil
178 case params[:graph]
181 case params[:graph]
179 when "commits_per_month"
182 when "commits_per_month"
180 data = graph_commits_per_month(@repository)
183 data = graph_commits_per_month(@repository)
181 when "commits_per_author"
184 when "commits_per_author"
182 data = graph_commits_per_author(@repository)
185 data = graph_commits_per_author(@repository)
183 end
186 end
184 if data
187 if data
185 headers["Content-Type"] = "image/svg+xml"
188 headers["Content-Type"] = "image/svg+xml"
186 send_data(data, :type => "image/svg+xml", :disposition => "inline")
189 send_data(data, :type => "image/svg+xml", :disposition => "inline")
187 else
190 else
188 render_404
191 render_404
189 end
192 end
190 end
193 end
191
194
192 private
195 private
193 def find_project
196 def find_project
194 @project = Project.find(params[:id])
197 @project = Project.find(params[:id])
195 rescue ActiveRecord::RecordNotFound
198 rescue ActiveRecord::RecordNotFound
196 render_404
199 render_404
197 end
200 end
198
201
199 REV_PARAM_RE = %r{^[a-f0-9]*$}
202 REV_PARAM_RE = %r{^[a-f0-9]*$}
200
203
201 def find_repository
204 def find_repository
202 @project = Project.find(params[:id])
205 @project = Project.find(params[:id])
203 @repository = @project.repository
206 @repository = @project.repository
204 render_404 and return false unless @repository
207 render_404 and return false unless @repository
205 @path = params[:path].join('/') unless params[:path].nil?
208 @path = params[:path].join('/') unless params[:path].nil?
206 @path ||= ''
209 @path ||= ''
207 @rev = params[:rev]
210 @rev = params[:rev]
208 @rev_to = params[:rev_to]
211 @rev_to = params[:rev_to]
209 raise InvalidRevisionParam unless @rev.to_s.match(REV_PARAM_RE) && @rev.to_s.match(REV_PARAM_RE)
212 raise InvalidRevisionParam unless @rev.to_s.match(REV_PARAM_RE) && @rev.to_s.match(REV_PARAM_RE)
210 rescue ActiveRecord::RecordNotFound
213 rescue ActiveRecord::RecordNotFound
211 render_404
214 render_404
212 rescue InvalidRevisionParam
215 rescue InvalidRevisionParam
213 show_error_not_found
216 show_error_not_found
214 end
217 end
215
218
216 def show_error_not_found
219 def show_error_not_found
217 render_error l(:error_scm_not_found)
220 render_error l(:error_scm_not_found)
218 end
221 end
219
222
220 # Handler for Redmine::Scm::Adapters::CommandFailed exception
223 # Handler for Redmine::Scm::Adapters::CommandFailed exception
221 def show_error_command_failed(exception)
224 def show_error_command_failed(exception)
222 render_error l(:error_scm_command_failed, exception.message)
225 render_error l(:error_scm_command_failed, exception.message)
223 end
226 end
224
227
225 def graph_commits_per_month(repository)
228 def graph_commits_per_month(repository)
226 @date_to = Date.today
229 @date_to = Date.today
227 @date_from = @date_to << 11
230 @date_from = @date_to << 11
228 @date_from = Date.civil(@date_from.year, @date_from.month, 1)
231 @date_from = Date.civil(@date_from.year, @date_from.month, 1)
229 commits_by_day = repository.changesets.count(:all, :group => :commit_date, :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
232 commits_by_day = repository.changesets.count(:all, :group => :commit_date, :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
230 commits_by_month = [0] * 12
233 commits_by_month = [0] * 12
231 commits_by_day.each {|c| commits_by_month[c.first.to_date.months_ago] += c.last }
234 commits_by_day.each {|c| commits_by_month[c.first.to_date.months_ago] += c.last }
232
235
233 changes_by_day = repository.changes.count(:all, :group => :commit_date, :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
236 changes_by_day = repository.changes.count(:all, :group => :commit_date, :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
234 changes_by_month = [0] * 12
237 changes_by_month = [0] * 12
235 changes_by_day.each {|c| changes_by_month[c.first.to_date.months_ago] += c.last }
238 changes_by_day.each {|c| changes_by_month[c.first.to_date.months_ago] += c.last }
236
239
237 fields = []
240 fields = []
238 month_names = l(:actionview_datehelper_select_month_names_abbr).split(',')
241 month_names = l(:actionview_datehelper_select_month_names_abbr).split(',')
239 12.times {|m| fields << month_names[((Date.today.month - 1 - m) % 12)]}
242 12.times {|m| fields << month_names[((Date.today.month - 1 - m) % 12)]}
240
243
241 graph = SVG::Graph::Bar.new(
244 graph = SVG::Graph::Bar.new(
242 :height => 300,
245 :height => 300,
243 :width => 800,
246 :width => 800,
244 :fields => fields.reverse,
247 :fields => fields.reverse,
245 :stack => :side,
248 :stack => :side,
246 :scale_integers => true,
249 :scale_integers => true,
247 :step_x_labels => 2,
250 :step_x_labels => 2,
248 :show_data_values => false,
251 :show_data_values => false,
249 :graph_title => l(:label_commits_per_month),
252 :graph_title => l(:label_commits_per_month),
250 :show_graph_title => true
253 :show_graph_title => true
251 )
254 )
252
255
253 graph.add_data(
256 graph.add_data(
254 :data => commits_by_month[0..11].reverse,
257 :data => commits_by_month[0..11].reverse,
255 :title => l(:label_revision_plural)
258 :title => l(:label_revision_plural)
256 )
259 )
257
260
258 graph.add_data(
261 graph.add_data(
259 :data => changes_by_month[0..11].reverse,
262 :data => changes_by_month[0..11].reverse,
260 :title => l(:label_change_plural)
263 :title => l(:label_change_plural)
261 )
264 )
262
265
263 graph.burn
266 graph.burn
264 end
267 end
265
268
266 def graph_commits_per_author(repository)
269 def graph_commits_per_author(repository)
267 commits_by_author = repository.changesets.count(:all, :group => :committer)
270 commits_by_author = repository.changesets.count(:all, :group => :committer)
268 commits_by_author.sort! {|x, y| x.last <=> y.last}
271 commits_by_author.sort! {|x, y| x.last <=> y.last}
269
272
270 changes_by_author = repository.changes.count(:all, :group => :committer)
273 changes_by_author = repository.changes.count(:all, :group => :committer)
271 h = changes_by_author.inject({}) {|o, i| o[i.first] = i.last; o}
274 h = changes_by_author.inject({}) {|o, i| o[i.first] = i.last; o}
272
275
273 fields = commits_by_author.collect {|r| r.first}
276 fields = commits_by_author.collect {|r| r.first}
274 commits_data = commits_by_author.collect {|r| r.last}
277 commits_data = commits_by_author.collect {|r| r.last}
275 changes_data = commits_by_author.collect {|r| h[r.first] || 0}
278 changes_data = commits_by_author.collect {|r| h[r.first] || 0}
276
279
277 fields = fields + [""]*(10 - fields.length) if fields.length<10
280 fields = fields + [""]*(10 - fields.length) if fields.length<10
278 commits_data = commits_data + [0]*(10 - commits_data.length) if commits_data.length<10
281 commits_data = commits_data + [0]*(10 - commits_data.length) if commits_data.length<10
279 changes_data = changes_data + [0]*(10 - changes_data.length) if changes_data.length<10
282 changes_data = changes_data + [0]*(10 - changes_data.length) if changes_data.length<10
280
283
281 # Remove email adress in usernames
284 # Remove email adress in usernames
282 fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') }
285 fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') }
283
286
284 graph = SVG::Graph::BarHorizontal.new(
287 graph = SVG::Graph::BarHorizontal.new(
285 :height => 400,
288 :height => 400,
286 :width => 800,
289 :width => 800,
287 :fields => fields,
290 :fields => fields,
288 :stack => :side,
291 :stack => :side,
289 :scale_integers => true,
292 :scale_integers => true,
290 :show_data_values => false,
293 :show_data_values => false,
291 :rotate_y_labels => false,
294 :rotate_y_labels => false,
292 :graph_title => l(:label_commits_per_author),
295 :graph_title => l(:label_commits_per_author),
293 :show_graph_title => true
296 :show_graph_title => true
294 )
297 )
295
298
296 graph.add_data(
299 graph.add_data(
297 :data => commits_data,
300 :data => commits_data,
298 :title => l(:label_revision_plural)
301 :title => l(:label_revision_plural)
299 )
302 )
300
303
301 graph.add_data(
304 graph.add_data(
302 :data => changes_data,
305 :data => changes_data,
303 :title => l(:label_change_plural)
306 :title => l(:label_change_plural)
304 )
307 )
305
308
306 graph.burn
309 graph.burn
307 end
310 end
308
311
309 end
312 end
310
313
311 class Date
314 class Date
312 def months_ago(date = Date.today)
315 def months_ago(date = Date.today)
313 (date.year - self.year)*12 + (date.month - self.month)
316 (date.year - self.year)*12 + (date.month - self.month)
314 end
317 end
315
318
316 def weeks_ago(date = Date.today)
319 def weeks_ago(date = Date.today)
317 (date.year - self.year)*52 + (date.cweek - self.cweek)
320 (date.year - self.year)*52 + (date.cweek - self.cweek)
318 end
321 end
319 end
322 end
320
323
321 class String
324 class String
322 def with_leading_slash
325 def with_leading_slash
323 starts_with?('/') ? self : "/#{self}"
326 starts_with?('/') ? self : "/#{self}"
324 end
327 end
325 end
328 end
@@ -1,28 +1,30
1 <h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => 'file', :revision => @rev } %></h2>
1 <h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => 'file', :revision => @rev } %></h2>
2
2
3 <p><%= render :partial => 'link_to_functions' %></p>
4
3 <% colors = Hash.new {|k,v| k[v] = (k.size % 12) } %>
5 <% colors = Hash.new {|k,v| k[v] = (k.size % 12) } %>
4
6
5 <div class="autoscroll">
7 <div class="autoscroll">
6 <table class="filecontent annotate CodeRay">
8 <table class="filecontent annotate CodeRay">
7 <tbody>
9 <tbody>
8 <% line_num = 1 %>
10 <% line_num = 1 %>
9 <% syntax_highlight(@path, to_utf8(@annotate.content)).each_line do |line| %>
11 <% syntax_highlight(@path, to_utf8(@annotate.content)).each_line do |line| %>
10 <% revision = @annotate.revisions[line_num-1] %>
12 <% revision = @annotate.revisions[line_num-1] %>
11 <tr class="bloc-<%= revision.nil? ? 0 : colors[revision.identifier || revision.revision] %>">
13 <tr class="bloc-<%= revision.nil? ? 0 : colors[revision.identifier || revision.revision] %>">
12 <th class="line-num"><%= line_num %></th>
14 <th class="line-num"><%= line_num %></th>
13 <td class="revision">
15 <td class="revision">
14 <%= (revision.identifier ? link_to(format_revision(revision.identifier), :action => 'revision', :id => @project, :rev => revision.identifier) : format_revision(revision.revision)) if revision %></td>
16 <%= (revision.identifier ? link_to(format_revision(revision.identifier), :action => 'revision', :id => @project, :rev => revision.identifier) : format_revision(revision.revision)) if revision %></td>
15 <td class="author"><%= h(revision.author.to_s.split('<').first) if revision %></td>
17 <td class="author"><%= h(revision.author.to_s.split('<').first) if revision %></td>
16 <td class="line-code"><pre><%= line %></pre></td>
18 <td class="line-code"><pre><%= line %></pre></td>
17 </tr>
19 </tr>
18 <% line_num += 1 %>
20 <% line_num += 1 %>
19 <% end %>
21 <% end %>
20 </tbody>
22 </tbody>
21 </table>
23 </table>
22 </div>
24 </div>
23
25
24 <% html_title(l(:button_annotate)) -%>
26 <% html_title(l(:button_annotate)) -%>
25
27
26 <% content_for :header_tags do %>
28 <% content_for :header_tags do %>
27 <%= stylesheet_link_tag 'scm' %>
29 <%= stylesheet_link_tag 'scm' %>
28 <% end %>
30 <% end %>
@@ -1,19 +1,10
1 <h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => (@entry ? @entry.kind : nil), :revision => @rev } %></h2>
1 <h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => (@entry ? @entry.kind : nil), :revision => @rev } %></h2>
2
2
3 <p>
3 <p><%= render :partial => 'link_to_functions' %></p>
4 <% if @repository.supports_cat? %>
5 <%= link_to l(:button_view), {:action => 'entry', :id => @project, :path => to_path_param(@path), :rev => @rev } %> |
6 <% end %>
7 <% if @repository.supports_annotate? %>
8 <%= link_to l(:button_annotate), {:action => 'annotate', :id => @project, :path => to_path_param(@path), :rev => @rev } %> |
9 <% end %>
10 <%= link_to(l(:button_download), {:action => 'entry', :id => @project, :path => to_path_param(@path), :rev => @rev, :format => 'raw' }) if @repository.supports_cat? %>
11 <%= "(#{number_to_human_size(@entry.size)})" if @entry.size %>
12 </p>
13
4
14 <%= render_properties(@properties) %>
5 <%= render_properties(@properties) %>
15
6
16 <%= render(:partial => 'revisions',
7 <%= render(:partial => 'revisions',
17 :locals => {:project => @project, :path => @path, :revisions => @changesets, :entry => @entry }) unless @changesets.empty? %>
8 :locals => {:project => @project, :path => @path, :revisions => @changesets, :entry => @entry }) unless @changesets.empty? %>
18
9
19 <% html_title(l(:label_change_plural)) -%>
10 <% html_title(l(:label_change_plural)) -%>
@@ -1,7 +1,9
1 <h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => 'file', :revision => @rev } %></h2>
1 <h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => 'file', :revision => @rev } %></h2>
2
2
3 <p><%= render :partial => 'link_to_functions' %></p>
4
3 <%= render :partial => 'common/file', :locals => {:filename => @path, :content => @content} %>
5 <%= render :partial => 'common/file', :locals => {:filename => @path, :content => @content} %>
4
6
5 <% content_for :header_tags do %>
7 <% content_for :header_tags do %>
6 <%= stylesheet_link_tag "scm" %>
8 <%= stylesheet_link_tag "scm" %>
7 <% end %>
9 <% end %>
General Comments 0
You need to be logged in to leave comments. Login now