##// END OF EJS Templates
SVN commits are now stored in the database, and added to the activity view and the search engine....
Jean-Philippe Lang -
r374:16f9f50f50db
parent child
Show More
@@ -0,0 +1,22
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
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
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 class Change < ActiveRecord::Base
19 belongs_to :changeset
20
21 validates_presence_of :changeset_id, :action, :path
22 end
@@ -0,0 +1,25
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
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
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 class Changeset < ActiveRecord::Base
19 belongs_to :repository
20 has_many :changes, :dependent => :delete_all
21
22 validates_presence_of :repository_id, :revision, :committed_on
23 validates_numericality_of :revision, :only_integer => true
24 validates_uniqueness_of :revision, :scope => :repository_id
25 end
@@ -0,0 +1,20
1 <table class="list">
2 <thead><tr>
3 <th>#</th>
4 <th><%= l(:field_author) %></th>
5 <th><%= l(:label_date) %></th>
6 <th><%= l(:field_comment) %></th>
7 <th></th>
8 </tr></thead>
9 <tbody>
10 <% changesets.each do |changeset| %>
11 <tr class="<%= cycle 'odd', 'even' %>">
12 <th align="center"><%= link_to changeset.revision, :action => 'revision', :id => project, :rev => changeset.revision %></th>
13 <td align="center"><em><%=h changeset.committer %></em></td>
14 <td align="center"><%= format_time(changeset.committed_on) %></td>
15 <td style="width:70%"><%= textilizable(changeset.comment) %></td>
16 <td align="center"><%= link_to 'Diff', :action => 'diff', :id => project, :path => path, :rev => changeset.revision if entry && entry.is_file? && changeset != changesets.last %></td>
17 </tr>
18 <% end %>
19 </tbody>
20 </table> No newline at end of file
@@ -0,0 +1,16
1 class CreateChangesets < ActiveRecord::Migration
2 def self.up
3 create_table :changesets do |t|
4 t.column :repository_id, :integer, :null => false
5 t.column :revision, :integer, :null => false
6 t.column :committer, :string, :limit => 30
7 t.column :committed_on, :datetime, :null => false
8 t.column :comment, :text
9 end
10 add_index :changesets, [:repository_id, :revision], :unique => true, :name => :changesets_repos_rev
11 end
12
13 def self.down
14 drop_table :changesets
15 end
16 end
@@ -0,0 +1,16
1 class CreateChanges < ActiveRecord::Migration
2 def self.up
3 create_table :changes do |t|
4 t.column :changeset_id, :integer, :null => false
5 t.column :action, :string, :limit => 1, :default => "", :null => false
6 t.column :path, :string, :default => "", :null => false
7 t.column :from_path, :string
8 t.column :from_revision, :integer
9 end
10 add_index :changes, [:changeset_id], :name => :changesets_changeset_id
11 end
12
13 def self.down
14 drop_table :changes
15 end
16 end
@@ -519,6 +519,17 class ProjectsController < ApplicationController
519 @show_wiki_edits = 1
519 @show_wiki_edits = 1
520 end
520 end
521
521
522 unless @project.repository.nil? || params[:show_changesets] == "0"
523 @project.repository.changesets.find(:all, :conditions => ["#{Changeset.table_name}.committed_on BETWEEN ? AND ?", @date_from, @date_to]).each { |i|
524 def i.created_on
525 self.committed_on
526 end
527 @events_by_day[i.created_on.to_date] ||= []
528 @events_by_day[i.created_on.to_date] << i
529 }
530 @show_changesets = 1
531 end
532
522 render :layout => false if request.xhr?
533 render :layout => false if request.xhr?
523 end
534 end
524
535
@@ -581,10 +592,10 class ProjectsController < ApplicationController
581 @question = params[:q] || ""
592 @question = params[:q] || ""
582 @question.strip!
593 @question.strip!
583 @all_words = params[:all_words] || (params[:submit] ? false : true)
594 @all_words = params[:all_words] || (params[:submit] ? false : true)
584 @scope = params[:scope] || (params[:submit] ? [] : %w(issues news documents wiki) )
595 @scope = params[:scope] || (params[:submit] ? [] : %w(issues changesets news documents wiki) )
585 if !@question.empty?
596 # tokens must be at least 3 character long
586 # tokens must be at least 3 character long
597 @tokens = @question.split.uniq.select {|w| w.length > 2 }
587 @tokens = @question.split.uniq.select {|w| w.length > 2 }
598 if !@tokens.empty?
588 # no more than 5 tokens to search for
599 # no more than 5 tokens to search for
589 @tokens.slice! 5..-1 if @tokens.size > 5
600 @tokens.slice! 5..-1 if @tokens.size > 5
590 # strings used in sql like statement
601 # strings used in sql like statement
@@ -596,7 +607,10 class ProjectsController < ApplicationController
596 @results += @project.news.find(:all, :limit => limit, :conditions => [ (["(LOWER(title) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort], :include => :author ) if @scope.include? 'news'
607 @results += @project.news.find(:all, :limit => limit, :conditions => [ (["(LOWER(title) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort], :include => :author ) if @scope.include? 'news'
597 @results += @project.documents.find(:all, :limit => limit, :conditions => [ (["(LOWER(title) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @scope.include? 'documents'
608 @results += @project.documents.find(:all, :limit => limit, :conditions => [ (["(LOWER(title) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @scope.include? 'documents'
598 @results += @project.wiki.pages.find(:all, :limit => limit, :include => :content, :conditions => [ (["(LOWER(title) like ? OR LOWER(text) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @project.wiki && @scope.include?('wiki')
609 @results += @project.wiki.pages.find(:all, :limit => limit, :include => :content, :conditions => [ (["(LOWER(title) like ? OR LOWER(text) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @project.wiki && @scope.include?('wiki')
610 @results += @project.repository.changesets.find(:all, :limit => limit, :conditions => [ (["(LOWER(comment) like ?)"] * like_tokens.size).join(operator), * (like_tokens).sort] ) if @project.repository && @scope.include?('changesets')
599 @question = @tokens.join(" ")
611 @question = @tokens.join(" ")
612 else
613 @question = ""
600 end
614 end
601 end
615 end
602
616
@@ -1,5 +1,5
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 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
@@ -20,9 +20,16 class RepositoriesController < ApplicationController
20 before_filter :find_project, :authorize
20 before_filter :find_project, :authorize
21
21
22 def show
22 def show
23 # get entries for the browse frame
23 @entries = @repository.scm.entries('')
24 @entries = @repository.scm.entries('')
24 show_error and return unless @entries
25 show_error and return unless @entries
25 @latest_revision = @entries.revisions.latest
26 # check if new revisions have been committed in the repository
27 scm_latestrev = @entries.revisions.latest
28 if Setting.autofetch_changesets? && scm_latestrev && ((@repository.latest_changeset.nil?) || (@repository.latest_changeset.revision < scm_latestrev.identifier.to_i))
29 @repository.fetch_changesets
30 @repository.reload
31 end
32 @changesets = @repository.changesets.find(:all, :limit => 5, :order => "committed_on DESC")
26 end
33 end
27
34
28 def browse
35 def browse
@@ -31,9 +38,11 class RepositoriesController < ApplicationController
31 end
38 end
32
39
33 def revisions
40 def revisions
34 @entry = @repository.scm.entry(@path, @rev)
41 unless @path == ''
35 @revisions = @repository.scm.revisions(@path, @rev)
42 @entry = @repository.scm.entry(@path, @rev)
36 show_error and return unless @entry && @revisions
43 show_error and return unless @entry
44 end
45 @changesets = @repository.changesets_for_path(@path)
37 end
46 end
38
47
39 def entry
48 def entry
@@ -45,9 +54,8 class RepositoriesController < ApplicationController
45 end
54 end
46
55
47 def revision
56 def revision
48 @revisions = @repository.scm.revisions '', @rev, @rev, :with_paths => true
57 @changeset = @repository.changesets.find_by_revision(@rev)
49 show_error and return unless @revisions
58 show_error and return unless @changeset
50 @revision = @revisions.first
51 end
59 end
52
60
53 def diff
61 def diff
@@ -1,5 +1,5
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 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
@@ -17,6 +17,11
17
17
18 class Repository < ActiveRecord::Base
18 class Repository < ActiveRecord::Base
19 belongs_to :project
19 belongs_to :project
20 has_many :changesets, :dependent => :destroy, :order => 'revision DESC'
21 has_one :latest_changeset, :class_name => 'Changeset', :foreign_key => :repository_id, :order => 'revision DESC'
22
23 attr_protected :root_url
24
20 validates_presence_of :url
25 validates_presence_of :url
21 validates_format_of :url, :with => /^(http|https|svn|file):\/\/.+/i
26 validates_format_of :url, :with => /^(http|https|svn|file):\/\/.+/i
22
27
@@ -27,10 +32,55 class Repository < ActiveRecord::Base
27 end
32 end
28
33
29 def url=(str)
34 def url=(str)
30 unless str == self.url
35 super if root_url.blank?
31 self.attributes = {:root_url => nil }
36 end
32 @scm = nil
37
38 def changesets_for_path(path="")
39 path = "/#{path}%"
40 path = url.gsub(/^#{root_url}/, '') + path if root_url && root_url != url
41 path.squeeze!("/")
42 changesets.find(:all, :include => :changes,
43 :conditions => ["#{Change.table_name}.path LIKE ?", path])
44 end
45
46 def fetch_changesets
47 scm_info = scm.info
48 if scm_info
49 lastrev_identifier = scm_info.lastrev.identifier.to_i
50 if latest_changeset.nil? || latest_changeset.revision < lastrev_identifier
51 logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
52 identifier_from = latest_changeset ? latest_changeset.revision + 1 : 1
53 while (identifier_from <= lastrev_identifier)
54 # loads changesets by batches of 200
55 identifier_to = [identifier_from + 199, lastrev_identifier].min
56 revisions = scm.revisions('', identifier_to, identifier_from, :with_paths => true)
57 transaction do
58 revisions.reverse_each do |revision|
59 changeset = Changeset.create(:repository => self,
60 :revision => revision.identifier,
61 :committer => revision.author,
62 :committed_on => revision.time,
63 :comment => revision.message)
64
65 revision.paths.each do |change|
66 Change.create(:changeset => changeset,
67 :action => change[:action],
68 :path => change[:path],
69 :from_path => change[:from_path],
70 :from_revision => change[:from_revision])
71 end
72 end
73 end
74 identifier_from = identifier_to + 1
75 end
76 end
33 end
77 end
34 super
78 end
79
80 # fetch new changesets for all repositories
81 # can be called periodically by an external script
82 # eg. ruby script/runner "Repository.fetch_changesets"
83 def self.fetch_changesets
84 find(:all).each(&:fetch_changesets)
35 end
85 end
36 end
86 end
@@ -1,5 +1,5
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 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
@@ -39,20 +39,27 module SvnRepos
39 @url
39 @url
40 end
40 end
41
41
42 # finds the root url of the svn repository
42 # get info about the svn repository
43 def retrieve_root_url
43 def info
44 cmd = "svn info --xml #{target('')}"
44 cmd = "svn info --xml #{target('')}"
45 cmd << " --username #{@login} --password #{@password}" if @login
45 cmd << " --username #{@login} --password #{@password}" if @login
46 root_url = nil
46 info = nil
47 shellout(cmd) do |io|
47 shellout(cmd) do |io|
48 begin
48 begin
49 doc = REXML::Document.new(io)
49 doc = REXML::Document.new(io)
50 root_url = doc.elements["info/entry/repository/root"].text
50 #root_url = doc.elements["info/entry/repository/root"].text
51 info = Info.new({:root_url => doc.elements["info/entry/repository/root"].text,
52 :lastrev => Revision.new({
53 :identifier => doc.elements["info/entry/commit"].attributes['revision'],
54 :time => Time.parse(doc.elements["info/entry/commit/date"].text),
55 :author => (doc.elements["info/entry/commit/author"] ? doc.elements["info/entry/commit/author"].text : "")
56 })
57 })
51 rescue
58 rescue
52 end
59 end
53 end
60 end
54 return nil if $? && $?.exitstatus != 0
61 return nil if $? && $?.exitstatus != 0
55 root_url
62 info
56 rescue Errno::ENOENT => e
63 rescue Errno::ENOENT => e
57 return nil
64 return nil
58 end
65 end
@@ -83,7 +90,7 module SvnRepos
83 :lastrev => Revision.new({
90 :lastrev => Revision.new({
84 :identifier => entry.elements['commit'].attributes['revision'],
91 :identifier => entry.elements['commit'].attributes['revision'],
85 :time => Time.parse(entry.elements['commit'].elements['date'].text),
92 :time => Time.parse(entry.elements['commit'].elements['date'].text),
86 :author => (entry.elements['commit'].elements['author'] ? entry.elements['commit'].elements['author'].text : "anonymous")
93 :author => (entry.elements['commit'].elements['author'] ? entry.elements['commit'].elements['author'].text : "")
87 })
94 })
88 })
95 })
89 end
96 end
@@ -112,13 +119,15 module SvnRepos
112 paths = []
119 paths = []
113 logentry.elements.each("paths/path") do |path|
120 logentry.elements.each("paths/path") do |path|
114 paths << {:action => path.attributes['action'],
121 paths << {:action => path.attributes['action'],
115 :path => path.text
122 :path => path.text,
123 :from_path => path.attributes['copyfrom-path'],
124 :from_revision => path.attributes['copyfrom-rev']
116 }
125 }
117 end
126 end
118 paths.sort! { |x,y| x[:path] <=> y[:path] }
127 paths.sort! { |x,y| x[:path] <=> y[:path] }
119
128
120 revisions << Revision.new({:identifier => logentry.attributes['revision'],
129 revisions << Revision.new({:identifier => logentry.attributes['revision'],
121 :author => (logentry.elements['author'] ? logentry.elements['author'].text : "anonymous"),
130 :author => (logentry.elements['author'] ? logentry.elements['author'].text : ""),
122 :time => Time.parse(logentry.elements['date'].text),
131 :time => Time.parse(logentry.elements['date'].text),
123 :message => logentry.elements['msg'].text,
132 :message => logentry.elements['msg'].text,
124 :paths => paths
133 :paths => paths
@@ -171,7 +180,12 module SvnRepos
171 raise CommandFailed
180 raise CommandFailed
172 end
181 end
173
182
174 private
183 private
184 def retrieve_root_url
185 info = self.info
186 info ? info.root_url : nil
187 end
188
175 def target(path)
189 def target(path)
176 path ||= ""
190 path ||= ""
177 base = path.match(/^\//) ? root_url : url
191 base = path.match(/^\//) ? root_url : url
@@ -207,6 +221,14 module SvnRepos
207 end
221 end
208 end
222 end
209
223
224 class Info
225 attr_accessor :root_url, :lastrev
226 def initialize(attributes={})
227 self.root_url = attributes[:root_url] if attributes[:root_url]
228 self.lastrev = attributes[:lastrev]
229 end
230 end
231
210 class Entry
232 class Entry
211 attr_accessor :name, :path, :kind, :size, :lastrev
233 attr_accessor :name, :path, :kind, :size, :lastrev
212 def initialize(attributes={})
234 def initialize(attributes={})
@@ -30,7 +30,7
30 <%= hidden_field_tag "repository_enabled", 0 %>
30 <%= hidden_field_tag "repository_enabled", 0 %>
31 <div id="repository">
31 <div id="repository">
32 <% fields_for :repository, @project.repository, { :builder => TabularFormBuilder, :lang => current_language} do |repository| %>
32 <% fields_for :repository, @project.repository, { :builder => TabularFormBuilder, :lang => current_language} do |repository| %>
33 <p><%= repository.text_field :url, :size => 60, :required => true %><br />(http://, https://, svn://, file:///)</p>
33 <p><%= repository.text_field :url, :size => 60, :required => true, :disabled => (@project.repository && !@project.repository.root_url.blank?) %><br />(http://, https://, svn://, file:///)</p>
34 <p><%= repository.text_field :login, :size => 30 %></p>
34 <p><%= repository.text_field :login, :size => 30 %></p>
35 <p><%= repository.password_field :password, :size => 30 %></p>
35 <p><%= repository.password_field :password, :size => 30 %></p>
36 <% end %>
36 <% end %>
@@ -7,6 +7,7
7 <%= select_year(@year, :prefix => "year", :discard_type => true) %></p>
7 <%= select_year(@year, :prefix => "year", :discard_type => true) %></p>
8 <p>
8 <p>
9 <%= check_box_tag 'show_issues', 1, @show_issues %><%= hidden_field_tag 'show_issues', 0, :id => nil %> <%=l(:label_issue_plural)%><br />
9 <%= check_box_tag 'show_issues', 1, @show_issues %><%= hidden_field_tag 'show_issues', 0, :id => nil %> <%=l(:label_issue_plural)%><br />
10 <% if @project.repository %><%= check_box_tag 'show_changesets', 1, @show_changesets %><%= hidden_field_tag 'show_changesets', 0, :id => nil %> <%=l(:label_revision_plural)%><br /><% end %>
10 <%= check_box_tag 'show_news', 1, @show_news %><%= hidden_field_tag 'show_news', 0, :id => nil %> <%=l(:label_news_plural)%><br />
11 <%= check_box_tag 'show_news', 1, @show_news %><%= hidden_field_tag 'show_news', 0, :id => nil %> <%=l(:label_news_plural)%><br />
11 <%= check_box_tag 'show_files', 1, @show_files %><%= hidden_field_tag 'show_files', 0, :id => nil %> <%=l(:label_attachment_plural)%><br />
12 <%= check_box_tag 'show_files', 1, @show_files %><%= hidden_field_tag 'show_files', 0, :id => nil %> <%=l(:label_attachment_plural)%><br />
12 <%= check_box_tag 'show_documents', 1, @show_documents %><%= hidden_field_tag 'show_documents', 0, :id => nil %> <%=l(:label_document_plural)%><br />
13 <%= check_box_tag 'show_documents', 1, @show_documents %><%= hidden_field_tag 'show_documents', 0, :id => nil %> <%=l(:label_document_plural)%><br />
@@ -39,6 +40,9
39 <% elsif e.is_a? WikiContent.versioned_class %>
40 <% elsif e.is_a? WikiContent.versioned_class %>
40 <%= e.created_on.strftime("%H:%M") %> <%=l(:label_wiki_edit)%>: <%= link_to h(WikiPage.pretty_title(e.title)), :controller => 'wiki', :page => e.title %> (<%= link_to '#' + e.version.to_s, :controller => 'wiki', :page => e.title, :version => e.version %>)<br />
41 <%= e.created_on.strftime("%H:%M") %> <%=l(:label_wiki_edit)%>: <%= link_to h(WikiPage.pretty_title(e.title)), :controller => 'wiki', :page => e.title %> (<%= link_to '#' + e.version.to_s, :controller => 'wiki', :page => e.title, :version => e.version %>)<br />
41 <% unless e.comment.blank? %><em><%=h e.comment %></em><% end %>
42 <% unless e.comment.blank? %><em><%=h e.comment %></em><% end %>
43 <% elsif e.is_a? Changeset %>
44 <%= e.created_on.strftime("%H:%M") %> <%=l(:label_revision)%> <%= link_to h(e.revision), :controller => 'repositories', :action => 'revision', :id => @project, :rev => e.revision %><br />
45 <em><%=h e.committer %><%= h(": #{e.comment}") unless e.comment.blank? %></em>
42 <% end %>
46 <% end %>
43 </p></li>
47 </p></li>
44
48
@@ -4,6 +4,9
4 <% form_tag({:action => 'search', :id => @project}, :method => :get) do %>
4 <% form_tag({:action => 'search', :id => @project}, :method => :get) do %>
5 <p><%= text_field_tag 'q', @question, :size => 30 %>
5 <p><%= text_field_tag 'q', @question, :size => 30 %>
6 <%= check_box_tag 'scope[]', 'issues', (@scope.include? 'issues') %> <label><%= l(:label_issue_plural) %></label>
6 <%= check_box_tag 'scope[]', 'issues', (@scope.include? 'issues') %> <label><%= l(:label_issue_plural) %></label>
7 <% if @project.repository %>
8 <%= check_box_tag 'scope[]', 'changesets', (@scope.include? 'changesets') %> <label><%= l(:label_revision_plural) %></label>
9 <% end %>
7 <%= check_box_tag 'scope[]', 'news', (@scope.include? 'news') %> <label><%= l(:label_news_plural) %></label>
10 <%= check_box_tag 'scope[]', 'news', (@scope.include? 'news') %> <label><%= l(:label_news_plural) %></label>
8 <%= check_box_tag 'scope[]', 'documents', (@scope.include? 'documents') %> <label><%= l(:label_document_plural) %></label>
11 <%= check_box_tag 'scope[]', 'documents', (@scope.include? 'documents') %> <label><%= l(:label_document_plural) %></label>
9 <% if @project.wiki %>
12 <% if @project.wiki %>
@@ -36,6 +39,10
36 <%=l(:label_wiki)%>: <%= link_to highlight_tokens(h(e.pretty_title), @tokens), :controller => 'wiki', :action => 'index', :id => @project, :page => e.title %><br />
39 <%=l(:label_wiki)%>: <%= link_to highlight_tokens(h(e.pretty_title), @tokens), :controller => 'wiki', :action => 'index', :id => @project, :page => e.title %><br />
37 <%= highlight_tokens(e.content.text, @tokens) %><br />
40 <%= highlight_tokens(e.content.text, @tokens) %><br />
38 <i><%= e.content.author ? e.content.author.name : "Anonymous" %>, <%= format_time(e.content.updated_on) %></i>
41 <i><%= e.content.author ? e.content.author.name : "Anonymous" %>, <%= format_time(e.content.updated_on) %></i>
42 <% elsif e.is_a? Changeset %>
43 <%=l(:label_revision)%> <%= link_to h(e.revision), :controller => 'repositories', :action => 'revision', :id => @project, :rev => e.revision %><br />
44 <%= highlight_tokens(e.comment, @tokens) %><br />
45 <em><%= e.committer.blank? ? e.committer : "Anonymous" %>, <%= format_time(e.committed_on) %></em>
39 <% end %>
46 <% end %>
40 </p></li>
47 </p></li>
41 <% end %>
48 <% end %>
@@ -5,10 +5,10
5 <% end %>
5 <% end %>
6 </div>
6 </div>
7
7
8 <h2><%= l(:label_revision) %> <%= @revision.identifier %></h2>
8 <h2><%= l(:label_revision) %> <%= @changeset.revision %></h2>
9
9
10 <p><em><%= @revision.author %>, <%= format_time(@revision.time) %></em></p>
10 <p><em><%= @changeset.committer %>, <%= format_time(@changeset.committed_on) %></em></p>
11 <%= textilizable @revision.message %>
11 <%= textilizable @changeset.comment %>
12
12
13 <div style="float:right;">
13 <div style="float:right;">
14 <div class="square action_A"></div> <div style="float:left;"><%= l(:label_added) %>&nbsp;</div>
14 <div class="square action_A"></div> <div style="float:left;"><%= l(:label_added) %>&nbsp;</div>
@@ -19,19 +19,19
19 <h3><%= l(:label_attachment_plural) %></h3>
19 <h3><%= l(:label_attachment_plural) %></h3>
20 <table class="list">
20 <table class="list">
21 <tbody>
21 <tbody>
22 <% @revision.paths.each do |path| %>
22 <% @changeset.changes.each do |change| %>
23 <tr class="<%= cycle 'odd', 'even' %>">
23 <tr class="<%= cycle 'odd', 'even' %>">
24 <td><div class="square action_<%= path[:action] %>"></div> <%= path[:path] %></td>
24 <td><div class="square action_<%= change.action %>"></div> <%= change.path %></td>
25 <td>
25 <td>
26 <% if path[:action] == "M" %>
26 <% if change.action == "M" %>
27 <%= link_to 'View diff', :action => 'diff', :id => @project, :path => path[:path], :rev => @revision.identifier %>
27 <%= link_to 'View diff', :action => 'diff', :id => @project, :path => change.path, :rev => @changeset.revision %>
28 <% end %>
28 <% end %>
29 </td>
29 </td>
30 </tr>
30 </tr>
31 <% end %>
31 <% end %>
32 </tbody>
32 </tbody>
33 </table>
33 </table>
34 <p><%= lwr(:label_modification, @revision.paths.length) %></p>
34 <p><%= lwr(:label_modification, @changeset.changes.length) %></p>
35
35
36 <% content_for :header_tags do %>
36 <% content_for :header_tags do %>
37 <%= stylesheet_link_tag "scm" %>
37 <%= stylesheet_link_tag "scm" %>
@@ -5,36 +5,17
5 <% end %>
5 <% end %>
6 </div>
6 </div>
7
7
8 <h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => @entry.kind, :revision => @rev } %></h2>
8 <h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => (@entry ? @entry.kind : nil), :revision => @rev } %></h2>
9
9
10 <% if @entry.is_file? %>
10 <% if @entry && @entry.is_file? %>
11 <h3><%=h @entry.name %></h3>
11 <h3><%=h @entry.name %></h3>
12 <p><%= link_to 'Download', {:action => 'entry', :id => @project, :path => @path, :rev => @rev, :format => 'raw' }, :class => "icon file" %> (<%= number_to_human_size @entry.size %>)</p>
12 <p><%= link_to 'Download', {:action => 'entry', :id => @project, :path => @path, :rev => @rev, :format => 'raw' }, :class => "icon file" %> (<%= number_to_human_size @entry.size %>)</p>
13 <% end %>
13 <% end %>
14
14
15 <h3>Revisions</h3>
15 <h3>Revisions</h3>
16
16
17 <table class="list">
17 <%= render :partial => 'revisions', :locals => {:project => @project, :path => @path, :changesets => @changesets, :entry => @entry }%>
18 <thead><tr>
18 <p><%= lwr(:label_modification, @changesets.length) %></p>
19 <th>#</th>
20 <th><%= l(:field_author) %></th>
21 <th><%= l(:label_date) %></th>
22 <th><%= l(:field_description) %></th>
23 <th></th>
24 </tr></thead>
25 <tbody>
26 <% @revisions.each do |revision| %>
27 <tr class="<%= cycle 'odd', 'even' %>">
28 <th align="center"><%= link_to revision.identifier, :action => 'revision', :id => @project, :rev => revision.identifier %></th>
29 <td align="center"><em><%=h revision.author %></em></td>
30 <td align="center"><%= format_time(revision.time) %></td>
31 <td style="width:70%"><%= textilizable(revision.message) %></td>
32 <td align="center"><%= link_to 'Diff', :action => 'diff', :id => @project, :path => @path, :rev => revision.identifier if @entry.is_file? && revision != @revisions.last %></td>
33 </tr>
34 <% end %>
35 </tbody>
36 </table>
37 <p><%= lwr(:label_modification, @revisions.length) %></p>
38
19
39 <% content_for :header_tags do %>
20 <% content_for :header_tags do %>
40 <%= stylesheet_link_tag "scm" %>
21 <%= stylesheet_link_tag "scm" %>
@@ -1,17 +1,14
1 <h2><%= l(:label_repository) %></h2>
1 <h2><%= l(:label_repository) %></h2>
2
2
3 <h3><%= l(:label_revision_plural) %></h3>
4 <% if @latest_revision %>
5 <p><%= l(:label_latest_revision) %>:
6 <%= link_to @latest_revision.identifier, :action => 'revision', :id => @project, :rev => @latest_revision.identifier %><br />
7 <em><%= @latest_revision.author %>, <%= format_time(@latest_revision.time) %></em></p>
8 <% end %>
9 <p><%= link_to l(:label_view_revisions), :action => 'revisions', :id => @project %></p>
10
11
12 <h3><%= l(:label_browse) %></h3>
3 <h3><%= l(:label_browse) %></h3>
13 <%= render :partial => 'dir_list' %>
4 <%= render :partial => 'dir_list' %>
14
5
6 <% unless @changesets.empty? %>
7 <h3><%= l(:label_latest_revision_plural) %></h3>
8 <%= render :partial => 'revisions', :locals => {:project => @project, :path => '', :changesets => @changesets, :entry => nil }%>
9 <p><%= link_to l(:label_view_revisions), :action => 'revisions', :id => @project %></p>
10 <% end %>
11
15 <% content_for :header_tags do %>
12 <% content_for :header_tags do %>
16 <%= stylesheet_link_tag "scm" %>
13 <%= stylesheet_link_tag "scm" %>
17 <% end %> No newline at end of file
14 <% end %>
@@ -45,6 +45,9
45 <p><label><%= l(:setting_feeds_limit) %></label>
45 <p><label><%= l(:setting_feeds_limit) %></label>
46 <%= text_field_tag 'settings[feeds_limit]', Setting.feeds_limit, :size => 6 %></p>
46 <%= text_field_tag 'settings[feeds_limit]', Setting.feeds_limit, :size => 6 %></p>
47
47
48 <p><label><%= l(:setting_autofetch_changesets) %></label>
49 <%= check_box_tag 'settings[autofetch_changesets]', 1, Setting.autofetch_changesets? %><%= hidden_field_tag 'settings[autofetch_changesets]', 0 %></p>
50
48 </div>
51 </div>
49 <%= submit_tag l(:button_save) %>
52 <%= submit_tag l(:button_save) %>
50 </div>
53 </div>
@@ -50,3 +50,5 host_name:
50 feeds_limit:
50 feeds_limit:
51 format: int
51 format: int
52 default: 15
52 default: 15
53 autofetch_changesets:
54 default: 1
@@ -160,6 +160,7 setting_host_name: Host Name
160 setting_text_formatting: Textformatierung
160 setting_text_formatting: Textformatierung
161 setting_wiki_compression: Wiki Historie komprimieren
161 setting_wiki_compression: Wiki Historie komprimieren
162 setting_feeds_limit: Limit Feed Inhalt
162 setting_feeds_limit: Limit Feed Inhalt
163 setting_autofetch_changesets: Autofetch SVN commits
163
164
164 label_user: Benutzer
165 label_user: Benutzer
165 label_user_plural: Benutzer
166 label_user_plural: Benutzer
@@ -315,6 +316,7 label_added: hinzugefügt
315 label_modified: geändert
316 label_modified: geändert
316 label_deleted: gelöscht
317 label_deleted: gelöscht
317 label_latest_revision: Aktuelleste Revision
318 label_latest_revision: Aktuelleste Revision
319 label_latest_revision_plural: Aktuelleste Revisionen
318 label_view_revisions: Revisionen anzeigen
320 label_view_revisions: Revisionen anzeigen
319 label_max_size: Maximale Größe
321 label_max_size: Maximale Größe
320 label_on: von
322 label_on: von
@@ -160,6 +160,7 setting_host_name: Host name
160 setting_text_formatting: Text formatting
160 setting_text_formatting: Text formatting
161 setting_wiki_compression: Wiki history compression
161 setting_wiki_compression: Wiki history compression
162 setting_feeds_limit: Feed content limit
162 setting_feeds_limit: Feed content limit
163 setting_autofetch_changesets: Autofetch SVN commits
163
164
164 label_user: User
165 label_user: User
165 label_user_plural: Users
166 label_user_plural: Users
@@ -315,6 +316,7 label_added: added
315 label_modified: modified
316 label_modified: modified
316 label_deleted: deleted
317 label_deleted: deleted
317 label_latest_revision: Latest revision
318 label_latest_revision: Latest revision
319 label_latest_revision_plural: Latest revisions
318 label_view_revisions: View revisions
320 label_view_revisions: View revisions
319 label_max_size: Maximum size
321 label_max_size: Maximum size
320 label_on: 'on'
322 label_on: 'on'
@@ -160,6 +160,7 setting_host_name: Nombre de anfitrión
160 setting_text_formatting: Formato de texto
160 setting_text_formatting: Formato de texto
161 setting_wiki_compression: Compresión de la historia de Wiki
161 setting_wiki_compression: Compresión de la historia de Wiki
162 setting_feeds_limit: Feed content limit
162 setting_feeds_limit: Feed content limit
163 setting_autofetch_changesets: Autofetch SVN commits
163
164
164 label_user: Usuario
165 label_user: Usuario
165 label_user_plural: Usuarios
166 label_user_plural: Usuarios
@@ -315,6 +316,7 label_added: agregado
315 label_modified: modificado
316 label_modified: modificado
316 label_deleted: suprimido
317 label_deleted: suprimido
317 label_latest_revision: La revisión más última
318 label_latest_revision: La revisión más última
319 label_latest_revision_plural: Latest revisions
318 label_view_revisions: Ver las revisiones
320 label_view_revisions: Ver las revisiones
319 label_max_size: Tamaño máximo
321 label_max_size: Tamaño máximo
320 label_on: en
322 label_on: en
@@ -160,6 +160,7 setting_host_name: Nom d'hôte
160 setting_text_formatting: Formatage du texte
160 setting_text_formatting: Formatage du texte
161 setting_wiki_compression: Compression historique wiki
161 setting_wiki_compression: Compression historique wiki
162 setting_feeds_limit: Limite du contenu des flux RSS
162 setting_feeds_limit: Limite du contenu des flux RSS
163 setting_autofetch_changesets: Récupération auto. des commits SVN
163
164
164 label_user: Utilisateur
165 label_user: Utilisateur
165 label_user_plural: Utilisateurs
166 label_user_plural: Utilisateurs
@@ -315,6 +316,7 label_added: ajouté
315 label_modified: modifié
316 label_modified: modifié
316 label_deleted: supprimé
317 label_deleted: supprimé
317 label_latest_revision: Dernière révision
318 label_latest_revision: Dernière révision
319 label_latest_revision_plural: Dernières révisions
318 label_view_revisions: Voir les révisions
320 label_view_revisions: Voir les révisions
319 label_max_size: Taille maximale
321 label_max_size: Taille maximale
320 label_on: sur
322 label_on: sur
@@ -160,6 +160,7 setting_host_name: Nome host
160 setting_text_formatting: Formattazione testo
160 setting_text_formatting: Formattazione testo
161 setting_wiki_compression: Compressione di storia di Wiki
161 setting_wiki_compression: Compressione di storia di Wiki
162 setting_feeds_limit: Feed content limit
162 setting_feeds_limit: Feed content limit
163 setting_autofetch_changesets: Autofetch SVN commits
163
164
164 label_user: Utente
165 label_user: Utente
165 label_user_plural: Utenti
166 label_user_plural: Utenti
@@ -315,6 +316,7 label_added: aggiunto
315 label_modified: modificato
316 label_modified: modificato
316 label_deleted: eliminato
317 label_deleted: eliminato
317 label_latest_revision: Ultima versione
318 label_latest_revision: Ultima versione
319 label_latest_revision_plural: Latest revisions
318 label_view_revisions: Mostra versioni
320 label_view_revisions: Mostra versioni
319 label_max_size: Dimensione massima
321 label_max_size: Dimensione massima
320 label_on: 'on'
322 label_on: 'on'
@@ -161,6 +161,7 setting_host_name: ホスト名
161 setting_text_formatting: テキストの書式
161 setting_text_formatting: テキストの書式
162 setting_wiki_compression: Wiki history compression
162 setting_wiki_compression: Wiki history compression
163 setting_feeds_limit: Feed content limit
163 setting_feeds_limit: Feed content limit
164 setting_autofetch_changesets: Autofetch SVN commits
164
165
165 label_user: ユーザ
166 label_user: ユーザ
166 label_user_plural: ユーザ
167 label_user_plural: ユーザ
@@ -316,6 +317,7 label_added: 追加された
316 label_modified: 変更された
317 label_modified: 変更された
317 label_deleted: 削除された
318 label_deleted: 削除された
318 label_latest_revision: 最新リビジョン
319 label_latest_revision: 最新リビジョン
320 label_latest_revision_plural: Latest revisions
319 label_view_revisions: リビジョンを見る
321 label_view_revisions: リビジョンを見る
320 label_max_size: 最大サイズ
322 label_max_size: 最大サイズ
321 label_on:
323 label_on:
General Comments 0
You need to be logged in to leave comments. Login now